All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/15] V4L camera control enhancements
@ 2012-04-17 10:09 Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 01/15] V4L: Extend V4L2_CID_COLORFX with more image effects Sylwester Nawrocki
                   ` (14 more replies)
  0 siblings, 15 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki

Hello,

this is a second iteration of my camera control patches. Besides the 
previous ones, it also includes the scene mode and 3A lock controls.
The 3A lock bitmask control allows to lock/unlock automatic exposure, 
white balance and focus adjustments. It is useful for pre-focus 
for instance.

I had been a little hesitant about introducing the scene mode control, 
however it is really needed, since some sensors with more advanced ISPs
or the ISPs inside host processors running their own firmware support 
the scene modes through a single configuration register.

The controls included in this series have been successfully used in 
the Samsung Android kernels for several years now. I'd like to extend
the V4L2 API to include at least most of the basic functionality 
available there.

Changes since v1 (implicit):
 - the V4L2_CID_AUTO_FOCUS_FACE_PRIORITY control merged with
   V4L2_CID_AUTO_FOCUS_FACE_AREA,
 - many minor documentation corrections,
 - removed "08/23 V4L: camera control class..." patch, which got 
   accidentally added at v1,
 - added V4L2_CID_SCENE_MODE and V4L2_CID_3A_LOCK controls,
 - added vivi patch for testing.

Any comments are welcome. I'd like to get this patch set merged for v3.5.
Maybe except the 3 focus related patches, since I'm not entirely happy 
with those API additions. I'll try to seek some time to complete those 
too though.

The patches will be also available in few hours at:
http://git.infradead.org/users/kmpark/linux-samsung/shortlog/refs/heads/v4l-controls-s5c73m3


Regards,

Sylwester Nawrocki
Samsung Poland R&D Center 


Sylwester Nawrocki (15):
  V4L: Extend V4L2_CID_COLORFX with more image effects
  V4L: Add helper function for standard integer menu controls
  V4L: Add camera exposure bias control
  V4L: Add camera white balance preset control
  V4L: Add camera wide dynamic range control
  V4L: Add camera image stabilization control
  V4L: Add camera ISO sensitivity controls
  V4L: Add camera exposure metering control
  V4L: Add camera scene mode control
  V4L: Add camera 3A lock control
  V4L: Add auto focus targets to the selections API
  V4L: Add auto focus targets to the subdev selections API
  V4L: Add camera auto focus controls
  V4L: Add S5C73M3 sensor sub-device driver
  vivi: Add controls

 Documentation/DocBook/media/v4l/biblio.xml         |   11 +
 Documentation/DocBook/media/v4l/controls.xml       |  549 ++++++++-
 Documentation/DocBook/media/v4l/dev-subdev.xml     |   27 +-
 Documentation/DocBook/media/v4l/selection-api.xml  |   33 +-
 .../DocBook/media/v4l/vidioc-g-selection.xml       |   11 +
 .../media/v4l/vidioc-subdev-g-selection.xml        |   14 +-
 drivers/media/video/Kconfig                        |    8 +
 drivers/media/video/Makefile                       |    1 +
 drivers/media/video/s5c73m3/Makefile               |    3 +
 drivers/media/video/s5c73m3/s5c73m3-ctrls.c        |  702 +++++++++++
 drivers/media/video/s5c73m3/s5c73m3-spi.c          |  126 ++
 drivers/media/video/s5c73m3/s5c73m3.c              | 1235 ++++++++++++++++++++
 drivers/media/video/s5c73m3/s5c73m3.h              |  446 +++++++
 drivers/media/video/v4l2-ctrls.c                   |  118 +-
 drivers/media/video/vivi.c                         |  111 +-
 include/linux/v4l2-subdev.h                        |    4 +
 include/linux/videodev2.h                          |  104 +-
 include/media/s5c73m3.h                            |   62 +
 include/media/v4l2-ctrls.h                         |   17 +
 19 files changed, 3551 insertions(+), 31 deletions(-)
 create mode 100644 drivers/media/video/s5c73m3/Makefile
 create mode 100644 drivers/media/video/s5c73m3/s5c73m3-ctrls.c
 create mode 100644 drivers/media/video/s5c73m3/s5c73m3-spi.c
 create mode 100644 drivers/media/video/s5c73m3/s5c73m3.c
 create mode 100644 drivers/media/video/s5c73m3/s5c73m3.h
 create mode 100644 include/media/s5c73m3.h

-- 
1.7.10


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH 01/15] V4L: Extend V4L2_CID_COLORFX with more image effects
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 10:51   ` Rémi Denis-Courmont
  2012-04-17 10:09 ` [PATCH 02/15] V4L: Add helper function for standard integer menu controls Sylwester Nawrocki
                   ` (13 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

This patch adds definition of additional color effects:
 - V4L2_COLORFX_AQUA,
 - V4L2_COLORFX_ART_FREEZE,
 - V4L2_COLORFX_SILHOUETTE,
 - V4L2_COLORFX_SOLARIZATION,
 - V4L2_COLORFX_ANTIQUE,
 - V4L2_COLORFX_ARBITRARY.

The control's type in the documentation is changed from 'enum' to 'menu'
- V4L2_CID_COLORFX has always been a menu, not an integer type control.

The V4L2_COLORFX_ARBITRARY option enables custom color effects, which are
impossible or impractical to define as the menu items. For example, the
devices may provide coefficients for Cb and Cr manipulation, which yield
many permutations, e.g. many slightly different color tints. Such devices
are better exporting their own API for precise control of non-standard
color effects.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 Documentation/DocBook/media/v4l/controls.xml |   91 ++++++++++++++++++++++----
 drivers/media/video/v4l2-ctrls.c             |    6 ++
 include/linux/videodev2.h                    |   26 +++++---
 3 files changed, 100 insertions(+), 23 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 6e2a2c6..0e2040d 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -284,19 +284,84 @@ minimum value disables backlight compensation.</entry>
 	  </row>
 	  <row id="v4l2-colorfx">
 	    <entry><constant>V4L2_CID_COLORFX</constant></entry>
-	    <entry>enum</entry>
-	    <entry>Selects a color effect. Possible values for
-<constant>enum v4l2_colorfx</constant> are:
-<constant>V4L2_COLORFX_NONE</constant> (0),
-<constant>V4L2_COLORFX_BW</constant> (1),
-<constant>V4L2_COLORFX_SEPIA</constant> (2),
-<constant>V4L2_COLORFX_NEGATIVE</constant> (3),
-<constant>V4L2_COLORFX_EMBOSS</constant> (4),
-<constant>V4L2_COLORFX_SKETCH</constant> (5),
-<constant>V4L2_COLORFX_SKY_BLUE</constant> (6),
-<constant>V4L2_COLORFX_GRASS_GREEN</constant> (7),
-<constant>V4L2_COLORFX_SKIN_WHITEN</constant> (8) and
-<constant>V4L2_COLORFX_VIVID</constant> (9).</entry>
+	    <entry>menu</entry>
+	    <entry>Selects a color effect. The following values are defined:
+	    </entry>
+	  </row><row>
+	  <entry></entry>
+	  <entry></entry>
+	    <entrytbl spanname="descr" cols="2">
+	      <tbody valign="top">
+		<row>
+		  <entry><constant>V4L2_COLORFX_NONE</constant>&nbsp;</entry>
+		  <entry>Color effect is disabled.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_ANTIQUE</constant>&nbsp;</entry>
+		  <entry>An aging (old photo) effect.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_ART_FREEZE</constant>&nbsp;</entry>
+		  <entry>Frost color effect.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_AQUA</constant>&nbsp;</entry>
+		  <entry>Water color, cool tone.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_BW</constant>&nbsp;</entry>
+		  <entry>Black and white.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_EMBOSS</constant>&nbsp;</entry>
+		  <entry>Emboss, the highlights and shadows replace light/dark boundaries
+		  and low contrast areas are set to a gray background.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_GRASS_GREEN</constant>&nbsp;</entry>
+		  <entry>Grass green.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_NEGATIVE</constant>&nbsp;</entry>
+		  <entry>Negative.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_SEPIA</constant>&nbsp;</entry>
+		  <entry>Sepia tone.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_SKETCH</constant>&nbsp;</entry>
+		  <entry>Sketch.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_SKIN_WHITEN</constant>&nbsp;</entry>
+		  <entry>Skin whiten.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_SKY_BLUE</constant>&nbsp;</entry>
+		  <entry>Sky blue.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_SOLARIZATION</constant>&nbsp;</entry>
+		  <entry>Solarization, the image is partially reversed in tone,
+		  only color values above or below a certain threshold are inverted.
+		  </entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_SILHOUETTE</constant>&nbsp;</entry>
+		  <entry>Silhouette (outline).</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_VIVID</constant>&nbsp;</entry>
+		  <entry>Vivid colors.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_COLORFX_ARBITRARY</constant>&nbsp;</entry>
+		  <entry>Arbitrary color effect, determined by other means, e.g.
+with driver private controls.</entry>
+		</row>
+	      </tbody>
+	    </entrytbl>
 	  </row>
 	  <row>
 	    <entry><constant>V4L2_CID_ROTATE</constant></entry>
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 34ff32d..13e6e8d 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -241,6 +241,12 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		"Grass Green",
 		"Skin Whiten",
 		"Vivid",
+		"Aqua",
+		"Art Freeze",
+		"Silhouette",
+		"Solarization",
+		"Antique",
+		"Arbitrary",
 		NULL
 	};
 	static const char * const tune_preemphasis[] = {
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 2503857..95ce588 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1269,16 +1269,22 @@ enum v4l2_power_line_frequency {
 #define V4L2_CID_COLOR_KILLER                   (V4L2_CID_BASE+30)
 #define V4L2_CID_COLORFX			(V4L2_CID_BASE+31)
 enum v4l2_colorfx {
-	V4L2_COLORFX_NONE	= 0,
-	V4L2_COLORFX_BW		= 1,
-	V4L2_COLORFX_SEPIA	= 2,
-	V4L2_COLORFX_NEGATIVE = 3,
-	V4L2_COLORFX_EMBOSS = 4,
-	V4L2_COLORFX_SKETCH = 5,
-	V4L2_COLORFX_SKY_BLUE = 6,
-	V4L2_COLORFX_GRASS_GREEN = 7,
-	V4L2_COLORFX_SKIN_WHITEN = 8,
-	V4L2_COLORFX_VIVID = 9,
+	V4L2_COLORFX_NONE			= 0,
+	V4L2_COLORFX_BW				= 1,
+	V4L2_COLORFX_SEPIA			= 2,
+	V4L2_COLORFX_NEGATIVE			= 3,
+	V4L2_COLORFX_EMBOSS			= 4,
+	V4L2_COLORFX_SKETCH			= 5,
+	V4L2_COLORFX_SKY_BLUE			= 6,
+	V4L2_COLORFX_GRASS_GREEN		= 7,
+	V4L2_COLORFX_SKIN_WHITEN		= 8,
+	V4L2_COLORFX_VIVID			= 9,
+	V4L2_COLORFX_AQUA			= 10,
+	V4L2_COLORFX_ART_FREEZE			= 11,
+	V4L2_COLORFX_SILHOUETTE			= 12,
+	V4L2_COLORFX_SOLARIZATION		= 13,
+	V4L2_COLORFX_ANTIQUE			= 14,
+	V4L2_COLORFX_ARBITRARY			= 15,
 };
 #define V4L2_CID_AUTOBRIGHTNESS			(V4L2_CID_BASE+32)
 #define V4L2_CID_BAND_STOP_FILTER		(V4L2_CID_BASE+33)
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 02/15] V4L: Add helper function for standard integer menu controls
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 01/15] V4L: Extend V4L2_CID_COLORFX with more image effects Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 03/15] V4L: Add camera exposure bias control Sylwester Nawrocki
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

This patch adds v4l2_ctrl_new_std_int_menu() helper function which can
be used in drivers for creating standard integer menu control. It is
similar to v4l2_ctrl_new_std_menu(), except it doesn't have a mask
parameter and an additional qmenu parameter allows passing an array
of signed 64-bit integers constituting the menu items.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/media/video/v4l2-ctrls.c |   21 +++++++++++++++++++++
 include/media/v4l2-ctrls.h       |   17 +++++++++++++++++
 2 files changed, 38 insertions(+)

diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 13e6e8d..aa0934c 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -1522,6 +1522,27 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
 }
 EXPORT_SYMBOL(v4l2_ctrl_new_std_menu);
 
+/* Helper function for standard integer menu controls */
+struct v4l2_ctrl *v4l2_ctrl_new_std_int_menu(struct v4l2_ctrl_handler *hdl,
+			const struct v4l2_ctrl_ops *ops,
+			u32 id, s32 max, s32 def, const s64 *qmenu_int)
+{
+	const char *name;
+	enum v4l2_ctrl_type type;
+	s32 min;
+	s32 step;
+	u32 flags;
+
+	v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
+	if (type != V4L2_CTRL_TYPE_INTEGER_MENU) {
+		handler_set_err(hdl, -EINVAL);
+		return NULL;
+	}
+	return v4l2_ctrl_new(hdl, ops, id, name, type,
+			     0, max, 0, def, flags, NULL, qmenu_int, NULL);
+}
+EXPORT_SYMBOL(v4l2_ctrl_new_std_int_menu);
+
 /* Add a control from another handler to this handler */
 struct v4l2_ctrl *v4l2_ctrl_add_ctrl(struct v4l2_ctrl_handler *hdl,
 					  struct v4l2_ctrl *ctrl)
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index 533315b..16581c0 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -348,6 +348,23 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
 			const struct v4l2_ctrl_ops *ops,
 			u32 id, s32 max, s32 mask, s32 def);
 
+/** v4l2_ctrl_new_std_int_menu() - Create a new standard V4L2 integer menu control.
+  * @hdl:	The control handler.
+  * @ops:	The control ops.
+  * @id:	The control ID.
+  * @max:	The control's maximum value.
+  * @def:	The control's default value.
+  * @qmenu_int:	The control's menu entries.
+  *
+  * Same as v4l2_ctrl_new_std_menu(), but @mask is set to 0 and it additionaly
+  * needs an array of integers determining the menu entries.
+  *
+  * If @id refers to a non-integer-menu control, then this function will return NULL.
+  */
+struct v4l2_ctrl *v4l2_ctrl_new_std_int_menu(struct v4l2_ctrl_handler *hdl,
+			const struct v4l2_ctrl_ops *ops,
+			u32 id, s32 max, s32 def, const s64 *qmenu_int);
+
 /** v4l2_ctrl_add_ctrl() - Add a control from another handler to this handler.
   * @hdl:	The control handler.
   * @ctrl:	The control to add.
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 03/15] V4L: Add camera exposure bias control
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 01/15] V4L: Extend V4L2_CID_COLORFX with more image effects Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 02/15] V4L: Add helper function for standard integer menu controls Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 04/15] V4L: Add camera white balance preset control Sylwester Nawrocki
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

The camera may in some conditions incorrectly determine the exposure,
and a manual automatic exposure correction may be needed. This patch
adds V4L2_CID_AUTO_EXPOSURE_BIAS control which allows to add some
offset in the automatic exposure control loop, to compensate for
frame under- or over-exposure.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 Documentation/DocBook/media/v4l/controls.xml |   16 ++++++++++++++++
 drivers/media/video/v4l2-ctrls.c             |    4 ++++
 include/linux/videodev2.h                    |    2 ++
 3 files changed, 22 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 0e2040d..69363dc 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -2840,6 +2840,22 @@ remain constant.</entry>
 	  <row><entry></entry></row>
 
 	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_EXPOSURE_BIAS</constant>&nbsp;</entry>
+	    <entry>integer menu</entry>
+	  </row><row><entry spanname="descr"> Determines the automatic
+exposure compensation, it is effective only when <constant>V4L2_CID_EXPOSURE_AUTO</constant>
+control is set to <constant>AUTO</constant>, <constant>SHUTTER_PRIORITY </constant>
+or <constant>APERTURE_PRIORITY</constant>.
+It is expressed in terms of EV, drivers should interpret the values as 0.001 EV
+units, where the value 1000 stands for +1 EV.
+<para>Increasing the exposure compensation value is equivalent to decreasing
+the exposure value (EV) and will increase the amount of light at the image
+sensor. The camera performs the exposure compensation by adjusting absolute
+exposure time and/or aperture.</para></entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
 	    <entry spanname="id"><constant>V4L2_CID_PAN_RELATIVE</constant>&nbsp;</entry>
 	    <entry>integer</entry>
 	  </row><row><entry spanname="descr">This control turns the
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index aa0934c..1f67bf2 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -603,6 +603,7 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_PRIVACY:			return "Privacy";
 	case V4L2_CID_IRIS_ABSOLUTE:		return "Iris, Absolute";
 	case V4L2_CID_IRIS_RELATIVE:		return "Iris, Relative";
+	case V4L2_CID_AUTO_EXPOSURE_BIAS:	return "Auto Exposure, Bias";
 
 	/* FM Radio Modulator control */
 	/* Keep the order of the 'case's the same as in videodev2.h! */
@@ -745,6 +746,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_RDS_TX_RADIO_TEXT:
 		*type = V4L2_CTRL_TYPE_STRING;
 		break;
+	case V4L2_CID_AUTO_EXPOSURE_BIAS:
+		*type = V4L2_CTRL_TYPE_INTEGER_MENU;
+		break;
 	case V4L2_CID_USER_CLASS:
 	case V4L2_CID_CAMERA_CLASS:
 	case V4L2_CID_MPEG_CLASS:
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 95ce588..fd2f400 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1727,6 +1727,8 @@ enum  v4l2_exposure_auto_type {
 #define V4L2_CID_IRIS_ABSOLUTE			(V4L2_CID_CAMERA_CLASS_BASE+17)
 #define V4L2_CID_IRIS_RELATIVE			(V4L2_CID_CAMERA_CLASS_BASE+18)
 
+#define V4L2_CID_AUTO_EXPOSURE_BIAS		(V4L2_CID_CAMERA_CLASS_BASE+19)
+
 /* FM Modulator class control IDs */
 #define V4L2_CID_FM_TX_CLASS_BASE		(V4L2_CTRL_CLASS_FM_TX | 0x900)
 #define V4L2_CID_FM_TX_CLASS			(V4L2_CTRL_CLASS_FM_TX | 1)
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 04/15] V4L: Add camera white balance preset control
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
                   ` (2 preceding siblings ...)
  2012-04-17 10:09 ` [PATCH 03/15] V4L: Add camera exposure bias control Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 13:23   ` Hans de Goede
  2012-04-17 10:09 ` [PATCH 05/15] V4L: Add camera wide dynamic range control Sylwester Nawrocki
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

Add V4L2_CID_WHITE_BALANCE_PRESET control for camera white balance
presets. The following items are defined:

 - V4L2_WHITE_BALANCE_NONE,
 - V4L2_WHITE_BALANCE_INCANDESCENT,
 - V4L2_WHITE_BALANCE_FLUORESCENT,
 - V4L2_WHITE_BALANCE_HORIZON,
 - V4L2_WHITE_BALANCE_DAYLIGHT,
 - V4L2_WHITE_BALANCE_FLASH,
 - V4L2_WHITE_BALANCE_CLOUDY,
 - V4L2_WHITE_BALANCE_SHADE,

This is a manual white balance control, in addition to V4L2_CID_RED_BALANCE,
V4L2_CID_BLUE_BALANCE and V4L2_CID_WHITE_BALANCE_TEMPERATURE. It's useful
for camera devices running more complex firmware and exposing white balance
preset selection in their user register interface.

Signed-off-by: HeungJun Kim <riverful.kim@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 Documentation/DocBook/media/v4l/controls.xml |   68 ++++++++++++++++++++++++++
 drivers/media/video/v4l2-ctrls.c             |   16 ++++++
 include/linux/videodev2.h                    |   12 +++++
 3 files changed, 96 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 69363dc..0ee3e9c 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3013,6 +3013,74 @@ camera sensor on or off, or specify its strength. Such band-stop filters can
 be used, for example, to filter out the fluorescent light component.</entry>
 	  </row>
 	  <row><entry></entry></row>
+
+	  <row id="v4l2-white-balance-preset">
+	    <entry spanname="id"><constant>V4L2_CID_WHITE_BALANCE_PRESET</constant>&nbsp;</entry>
+	    <entry>enum&nbsp;v4l2_white_balance_preset</entry>
+	  </row><row><entry spanname="descr">Sets a predefined white balance
+configuration. The presets determine color temperature of the light on a basis
+of which the camera performs white balance adjustments, in order to obtain most
+accurate color representation. This control has no effect when automatic white
+balance adjustments are enabled, i.e. <constant>V4L2_CID_AUTO_WHITE_BALANCE
+</constant> control is set to <constant>TRUE</constant> (1). The following white
+balance presets are listed in order of increasing color temperature.</entry>
+	  </row>
+	  <row>
+	    <entrytbl spanname="descr" cols="2">
+	      <tbody valign="top">
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_PRESET_NONE</constant>&nbsp;</entry>
+		  <entry>None of the presets is active, i.e. the white balance
+preset feature is disabled. It is useful when driver exposes other manual white
+balance controls, like <constant>V4L2_CID_RED_BALANCE</constant> and <constant>
+V4L2_CID_BLUE_BALANCE</constant>, that may render a configured preset invalid.
+</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_PRESET_INCANDESCENT</constant>&nbsp;</entry>
+		  <entry>White balance settings for incandescent (tungsten) lighting.
+It generally cools down the colors and corresponds approximately to 2500...3500 K
+color temperature range.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_PRESET_FLUORESCENT</constant>&nbsp;</entry>
+		  <entry>With this setting the camera will compensate for fluorescent
+lighting. It corresponds approximately to 4000...5000 K color temperature.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_PRESET_HORIZON</constant>&nbsp;</entry>
+		  <entry>White balance settings for horizon daylight.
+This corresponds approximately to 5000 K color temperature.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_PRESET_DAYLIGHT</constant>&nbsp;</entry>
+		  <entry>White balance settings for daylight (with clear sky).
+This corresponds approximately to 5000...6500 K color temperature.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_PRESET_FLASH</constant>&nbsp;</entry>
+		  <entry>With this setting the camera will compensate for the flash
+light. It slightly warms up the colors and corresponds roughly to 5000...5500 K
+color temperature.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_PRESET_CLOUDY</constant>&nbsp;</entry>
+		  <entry>White balance settings for moderately overcast sky.
+This option corresponds approximately to 6500...8000 K color temperature range
+and will make colors appear warmer than with the
+<constant>V4L2_WHITE_BALANCE_PRESET_DAYLIGHT</constant> preset.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_PRESET_SHADE</constant>&nbsp;</entry>
+		  <entry>White balance settings for shade or heavily overcast
+sky. It corresponds approximately to 9000...10000 K color temperature.
+</entry>
+		</row>
+	      </tbody>
+	    </entrytbl>
+	  </row>
+	  <row><entry></entry></row>
+
 	</tbody>
       </tgroup>
     </table>
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 1f67bf2..b6cd147 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -249,6 +249,17 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		"Arbitrary",
 		NULL
 	};
+	static const char * const white_balance_preset[] = {
+		"None",
+		"Incandescent",
+		"Fluorescent",
+		"Horizon",
+		"Daylight",
+		"Flash",
+		"Cloudy",
+		"Shade",
+		NULL,
+	};
 	static const char * const tune_preemphasis[] = {
 		"No Preemphasis",
 		"50 useconds",
@@ -418,6 +429,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		return camera_exposure_auto;
 	case V4L2_CID_COLORFX:
 		return colorfx;
+	case V4L2_CID_WHITE_BALANCE_PRESET:
+		return white_balance_preset;
 	case V4L2_CID_TUNE_PREEMPHASIS:
 		return tune_preemphasis;
 	case V4L2_CID_FLASH_LED_MODE:
@@ -605,6 +618,8 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_IRIS_RELATIVE:		return "Iris, Relative";
 	case V4L2_CID_AUTO_EXPOSURE_BIAS:	return "Auto Exposure, Bias";
 
+	case V4L2_CID_WHITE_BALANCE_PRESET:	return "White Balance, Preset";
+
 	/* FM Radio Modulator control */
 	/* Keep the order of the 'case's the same as in videodev2.h! */
 	case V4L2_CID_FM_TX_CLASS:		return "FM Radio Modulator Controls";
@@ -727,6 +742,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_STREAM_VBI_FMT:
 	case V4L2_CID_EXPOSURE_AUTO:
 	case V4L2_CID_COLORFX:
+	case V4L2_CID_WHITE_BALANCE_PRESET:
 	case V4L2_CID_TUNE_PREEMPHASIS:
 	case V4L2_CID_FLASH_LED_MODE:
 	case V4L2_CID_FLASH_STROBE_SOURCE:
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index fd2f400..537663a 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1729,6 +1729,18 @@ enum  v4l2_exposure_auto_type {
 
 #define V4L2_CID_AUTO_EXPOSURE_BIAS		(V4L2_CID_CAMERA_CLASS_BASE+19)
 
+#define V4L2_CID_WHITE_BALANCE_PRESET		(V4L2_CID_CAMERA_CLASS_BASE+20)
+enum v4l2_white_balance_preset {
+	V4L2_WHITE_BALANCE_PRESET_NONE		= 0,
+	V4L2_WHITE_BALANCE_PRESET_INCANDESCENT	= 1,
+	V4L2_WHITE_BALANCE_PRESET_FLUORESCENT	= 2,
+	V4L2_WHITE_BALANCE_PRESET_HORIZON	= 3,
+	V4L2_WHITE_BALANCE_PRESET_DAYLIGHT	= 4,
+	V4L2_WHITE_BALANCE_PRESET_FLASH		= 5,
+	V4L2_WHITE_BALANCE_PRESET_CLOUDY	= 6,
+	V4L2_WHITE_BALANCE_PRESET_SHADE		= 7,
+};
+
 /* FM Modulator class control IDs */
 #define V4L2_CID_FM_TX_CLASS_BASE		(V4L2_CTRL_CLASS_FM_TX | 0x900)
 #define V4L2_CID_FM_TX_CLASS			(V4L2_CTRL_CLASS_FM_TX | 1)
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 05/15] V4L: Add camera wide dynamic range control
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
                   ` (3 preceding siblings ...)
  2012-04-17 10:09 ` [PATCH 04/15] V4L: Add camera white balance preset control Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 06/15] V4L: Add camera image stabilization control Sylwester Nawrocki
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

The V4L2_CID_WIDE_DYNAMIC_RANGE camera class control allows to control
the camera wide dynamic range (WDR, HDR) feature. It can be used to
enable/disable WDR. For the WDR technique selection separate menu control
should be added.

Signed-off-by: HeungJun Kim <riverful.kim@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 Documentation/DocBook/media/v4l/controls.xml |   14 ++++++++++++++
 drivers/media/video/v4l2-ctrls.c             |    2 ++
 include/linux/videodev2.h                    |    2 ++
 3 files changed, 18 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 0ee3e9c..55882de 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3081,6 +3081,20 @@ sky. It corresponds approximately to 9000...10000 K color temperature.
 	  </row>
 	  <row><entry></entry></row>
 
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_WIDE_DYNAMIC_RANGE</constant></entry>
+	    <entry>boolean</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Enables or disables the camera's
+wide dynamic range feature.  This feature allows to obtain clear images
+in situations where intensity of the illumination varies significantly
+throughout the scene, i.e. there are simultaneously very dark and very
+bright areas. It is most commonly realized in cameras by combining
+two subsequent frames of different exposure times.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
 	</tbody>
       </tgroup>
     </table>
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index b6cd147..93bbf65 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -619,6 +619,7 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_AUTO_EXPOSURE_BIAS:	return "Auto Exposure, Bias";
 
 	case V4L2_CID_WHITE_BALANCE_PRESET:	return "White Balance, Preset";
+	case V4L2_CID_WIDE_DYNAMIC_RANGE:	return "Wide Dynamic Range";
 
 	/* FM Radio Modulator control */
 	/* Keep the order of the 'case's the same as in videodev2.h! */
@@ -710,6 +711,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM:
 	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
 	case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
+	case V4L2_CID_WIDE_DYNAMIC_RANGE:
 		*type = V4L2_CTRL_TYPE_BOOLEAN;
 		*min = 0;
 		*max = *step = 1;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 537663a..a4ac032 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1741,6 +1741,8 @@ enum v4l2_white_balance_preset {
 	V4L2_WHITE_BALANCE_PRESET_SHADE		= 7,
 };
 
+#define V4L2_CID_WIDE_DYNAMIC_RANGE		(V4L2_CID_CAMERA_CLASS_BASE+21)
+
 /* FM Modulator class control IDs */
 #define V4L2_CID_FM_TX_CLASS_BASE		(V4L2_CTRL_CLASS_FM_TX | 0x900)
 #define V4L2_CID_FM_TX_CLASS			(V4L2_CTRL_CLASS_FM_TX | 1)
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 06/15] V4L: Add camera image stabilization control
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
                   ` (4 preceding siblings ...)
  2012-04-17 10:09 ` [PATCH 05/15] V4L: Add camera wide dynamic range control Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 07/15] V4L: Add camera ISO sensitivity controls Sylwester Nawrocki
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

The V4L2_CID_IMAGE_STABILIZATION control allows to control the camera's
image stabilization feature. It can be used to enable/disable image
stabilization. If the image stabilization technique selection control
is needed, a separate menu control should be added.

Signed-off-by: HeungJun Kim <riverful.kim@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 Documentation/DocBook/media/v4l/controls.xml |   10 ++++++++++
 drivers/media/video/v4l2-ctrls.c             |    2 ++
 include/linux/videodev2.h                    |    1 +
 3 files changed, 13 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 55882de..010edc4 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3095,6 +3095,16 @@ two subsequent frames of different exposure times.</entry>
 	  </row>
 	  <row><entry></entry></row>
 
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_IMAGE_STABILIZATION</constant></entry>
+	    <entry>boolean</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Enables or disables image stabilization
+feature.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
 	</tbody>
       </tgroup>
     </table>
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index 93bbf65..a0d1b4a 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -620,6 +620,7 @@ const char *v4l2_ctrl_get_name(u32 id)
 
 	case V4L2_CID_WHITE_BALANCE_PRESET:	return "White Balance, Preset";
 	case V4L2_CID_WIDE_DYNAMIC_RANGE:	return "Wide Dynamic Range";
+	case V4L2_CID_IMAGE_STABILIZATION:	return "Image Stabilization";
 
 	/* FM Radio Modulator control */
 	/* Keep the order of the 'case's the same as in videodev2.h! */
@@ -712,6 +713,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_VIDEO_H264_VUI_SAR_ENABLE:
 	case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
 	case V4L2_CID_WIDE_DYNAMIC_RANGE:
+	case V4L2_CID_IMAGE_STABILIZATION:
 		*type = V4L2_CTRL_TYPE_BOOLEAN;
 		*min = 0;
 		*max = *step = 1;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index a4ac032..897bf7b 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1742,6 +1742,7 @@ enum v4l2_white_balance_preset {
 };
 
 #define V4L2_CID_WIDE_DYNAMIC_RANGE		(V4L2_CID_CAMERA_CLASS_BASE+21)
+#define V4L2_CID_IMAGE_STABILIZATION		(V4L2_CID_CAMERA_CLASS_BASE+22)
 
 /* FM Modulator class control IDs */
 #define V4L2_CID_FM_TX_CLASS_BASE		(V4L2_CTRL_CLASS_FM_TX | 0x900)
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 07/15] V4L: Add camera ISO sensitivity controls
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
                   ` (5 preceding siblings ...)
  2012-04-17 10:09 ` [PATCH 06/15] V4L: Add camera image stabilization control Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 08/15] V4L: Add camera exposure metering control Sylwester Nawrocki
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

Add ISO sensitivity and ISO auto/manual controls. The sensitivity
values are related to level of amplification of the analog signal
between image sensor and ADC. These controls allow to support sensors
exposing an interface to accept the ISO values directly.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 Documentation/DocBook/media/v4l/biblio.xml   |   11 +++++++++++
 Documentation/DocBook/media/v4l/controls.xml |   24 ++++++++++++++++++++++++
 drivers/media/video/v4l2-ctrls.c             |    5 ++++-
 include/linux/videodev2.h                    |    3 +++
 4 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/Documentation/DocBook/media/v4l/biblio.xml b/Documentation/DocBook/media/v4l/biblio.xml
index 7dc65c5..66a0ef2 100644
--- a/Documentation/DocBook/media/v4l/biblio.xml
+++ b/Documentation/DocBook/media/v4l/biblio.xml
@@ -197,4 +197,15 @@ in the frequency range from 87,5 to 108,0 MHz</title>
       <title>NTSC-4: United States RBDS Standard</title>
     </biblioentry>
 
+    <biblioentry id="iso12232">
+      <abbrev>ISO&nbsp;12232:2006</abbrev>
+      <authorgroup>
+	<corpauthor>International Organization for Standardization
+(<ulink url="http://www.iso.org">http://www.iso.org</ulink>)</corpauthor>
+      </authorgroup>
+      <title>Photography &mdash; Digital still cameras &mdash; Determination
+      of exposure index, ISO speed ratings, standard output sensitivity, and
+      recommended exposure index</title>
+    </biblioentry>
+
   </bibliography>
diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 010edc4..c50941e 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3105,6 +3105,30 @@ feature.</entry>
 	  </row>
 	  <row><entry></entry></row>
 
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_ISO_SENSITIVITY</constant>&nbsp;</entry>
+	    <entry>integer menu</entry>
+	  </row><row><entry spanname="descr">Determines ISO equivalent of an
+image sensor indicating the sensor's sensitivity to light. The numbers are
+expressed in arithmetic scale, as per <xref linkend="iso12232" /> standard,
+where doubling the sensor sensitivity is represented by doubling the numerical
+ISO value. Applications should interpret the values as standard ISO values
+multiplied by 1000, e.g. control value 800 stands for ISO 0.8. Drivers will
+usually support only a subset of standard ISO values.
+</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>&nbsp;</entry>
+	    <entry>boolean</entry>
+	  </row><row><entry spanname="descr">Enables automatic ISO sensitivity
+adjustments. The effect of setting <constant>V4L2_CID_ISO_SENSITIVITY</constant>
+while automatic ISO control is enabled is undefined, drivers should ignore such
+requests.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
 	</tbody>
       </tgroup>
     </table>
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index a0d1b4a..aa3d111 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -617,10 +617,11 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_IRIS_ABSOLUTE:		return "Iris, Absolute";
 	case V4L2_CID_IRIS_RELATIVE:		return "Iris, Relative";
 	case V4L2_CID_AUTO_EXPOSURE_BIAS:	return "Auto Exposure, Bias";
-
 	case V4L2_CID_WHITE_BALANCE_PRESET:	return "White Balance, Preset";
 	case V4L2_CID_WIDE_DYNAMIC_RANGE:	return "Wide Dynamic Range";
 	case V4L2_CID_IMAGE_STABILIZATION:	return "Image Stabilization";
+	case V4L2_CID_ISO_SENSITIVITY:		return "ISO Sensitivity";
+	case V4L2_CID_ISO_SENSITIVITY_AUTO:	return "ISO Sensitivity, Auto";
 
 	/* FM Radio Modulator control */
 	/* Keep the order of the 'case's the same as in videodev2.h! */
@@ -714,6 +715,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_VIDEO_MPEG4_QPEL:
 	case V4L2_CID_WIDE_DYNAMIC_RANGE:
 	case V4L2_CID_IMAGE_STABILIZATION:
+	case V4L2_CID_ISO_SENSITIVITY_AUTO:
 		*type = V4L2_CTRL_TYPE_BOOLEAN;
 		*min = 0;
 		*max = *step = 1;
@@ -766,6 +768,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_RDS_TX_RADIO_TEXT:
 		*type = V4L2_CTRL_TYPE_STRING;
 		break;
+	case V4L2_CID_ISO_SENSITIVITY:
 	case V4L2_CID_AUTO_EXPOSURE_BIAS:
 		*type = V4L2_CTRL_TYPE_INTEGER_MENU;
 		break;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 897bf7b..1c6d342 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1744,6 +1744,9 @@ enum v4l2_white_balance_preset {
 #define V4L2_CID_WIDE_DYNAMIC_RANGE		(V4L2_CID_CAMERA_CLASS_BASE+21)
 #define V4L2_CID_IMAGE_STABILIZATION		(V4L2_CID_CAMERA_CLASS_BASE+22)
 
+#define V4L2_CID_ISO_SENSITIVITY		(V4L2_CID_CAMERA_CLASS_BASE+23)
+#define V4L2_CID_ISO_SENSITIVITY_AUTO		(V4L2_CID_CAMERA_CLASS_BASE+24)
+
 /* FM Modulator class control IDs */
 #define V4L2_CID_FM_TX_CLASS_BASE		(V4L2_CTRL_CLASS_FM_TX | 0x900)
 #define V4L2_CID_FM_TX_CLASS			(V4L2_CTRL_CLASS_FM_TX | 1)
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 08/15] V4L: Add camera exposure metering control
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
                   ` (6 preceding siblings ...)
  2012-04-17 10:09 ` [PATCH 07/15] V4L: Add camera ISO sensitivity controls Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 09/15] V4L: Add camera scene mode control Sylwester Nawrocki
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

The V4L2_CID_EXPOSURE_METERING control allows to determine
a method used by the camera for measuring the amount of light
available for automatic exposure.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 Documentation/DocBook/media/v4l/controls.xml |   29 ++++++++++++++++++++++++++
 drivers/media/video/v4l2-ctrls.c             |   14 +++++++++++++
 include/linux/videodev2.h                    |    7 +++++++
 3 files changed, 50 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index c50941e..fc05f9d 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -2855,6 +2855,35 @@ exposure time and/or aperture.</para></entry>
 	  </row>
 	  <row><entry></entry></row>
 
+	  <row id="v4l2-exposure-metering">
+	    <entry spanname="id"><constant>V4L2_CID_EXPOSURE_METERING</constant>&nbsp;</entry>
+	    <entry>enum&nbsp;v4l2_exposure_metering</entry>
+	  </row><row><entry spanname="descr">Determines how the camera measures
+the amount of light available for the frame exposure. Possible values are:</entry>
+	  </row>
+	  <row>
+	    <entrytbl spanname="descr" cols="2">
+	      <tbody valign="top">
+		<row>
+		  <entry><constant>V4L2_EXPOSURE_METERING_AVERAGE</constant>&nbsp;</entry>
+		  <entry>Use the light information coming from the entire frame
+and average giving no weighting to any particular portion of the metered area.
+		  </entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_EXPOSURE_METERING_CENTER_WEIGHTED</constant>&nbsp;</entry>
+		  <entry>Average the light information coming from the entire frame
+giving priority to the center of the metered area.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_EXPOSURE_METERING_SPOT</constant>&nbsp;</entry>
+		  <entry>Measure only very small area at the center of the frame.</entry>
+		</row>
+	      </tbody>
+	    </entrytbl>
+	  </row>
+	  <row><entry></entry></row>
+
 	  <row>
 	    <entry spanname="id"><constant>V4L2_CID_PAN_RELATIVE</constant>&nbsp;</entry>
 	    <entry>integer</entry>
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index aa3d111..e037601 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -230,6 +230,12 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		"Aperture Priority Mode",
 		NULL
 	};
+	static const char * const camera_exposure_metering[] = {
+		"Average",
+		"Center Weighted",
+		"Spot",
+		NULL
+	};
 	static const char * const colorfx[] = {
 		"None",
 		"Black & White",
@@ -427,6 +433,12 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		return camera_power_line_frequency;
 	case V4L2_CID_EXPOSURE_AUTO:
 		return camera_exposure_auto;
+	case V4L2_CID_EXPOSURE_METERING:
+		return camera_exposure_metering;
+	case V4L2_CID_AUTO_FOCUS_AREA:
+		return camera_auto_focus_area;
+	case V4L2_CID_AUTO_FOCUS_DISTANCE:
+		return camera_auto_focus_distance;
 	case V4L2_CID_COLORFX:
 		return colorfx;
 	case V4L2_CID_WHITE_BALANCE_PRESET:
@@ -622,6 +634,7 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_IMAGE_STABILIZATION:	return "Image Stabilization";
 	case V4L2_CID_ISO_SENSITIVITY:		return "ISO Sensitivity";
 	case V4L2_CID_ISO_SENSITIVITY_AUTO:	return "ISO Sensitivity, Auto";
+	case V4L2_CID_EXPOSURE_METERING:	return "Exposure, Metering Mode";
 
 	/* FM Radio Modulator control */
 	/* Keep the order of the 'case's the same as in videodev2.h! */
@@ -762,6 +775,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
 	case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
 	case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
+	case V4L2_CID_EXPOSURE_METERING:
 		*type = V4L2_CTRL_TYPE_MENU;
 		break;
 	case V4L2_CID_RDS_TX_PS_NAME:
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 1c6d342..37ecd6a 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1747,6 +1747,13 @@ enum v4l2_white_balance_preset {
 #define V4L2_CID_ISO_SENSITIVITY		(V4L2_CID_CAMERA_CLASS_BASE+23)
 #define V4L2_CID_ISO_SENSITIVITY_AUTO		(V4L2_CID_CAMERA_CLASS_BASE+24)
 
+#define V4L2_CID_EXPOSURE_METERING		(V4L2_CID_CAMERA_CLASS_BASE+25)
+enum v4l2_exposure_metering_mode {
+	V4L2_EXPOSURE_METERING_AVERAGE		= 0,
+	V4L2_EXPOSURE_METERING_CENTER_WEIGHTED	= 1,
+	V4L2_EXPOSURE_METERING_SPOT		= 2,
+};
+
 /* FM Modulator class control IDs */
 #define V4L2_CID_FM_TX_CLASS_BASE		(V4L2_CTRL_CLASS_FM_TX | 0x900)
 #define V4L2_CID_FM_TX_CLASS			(V4L2_CTRL_CLASS_FM_TX | 1)
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 09/15] V4L: Add camera scene mode control
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
                   ` (7 preceding siblings ...)
  2012-04-17 10:09 ` [PATCH 08/15] V4L: Add camera exposure metering control Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 10/15] V4L: Add camera 3A lock control Sylwester Nawrocki
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

Add control for the scene mode feature available in image sensor
with more advanced ISP firmware. The V4L2_CID_SCENE_MODE menu
control allows to select a set of parameters or a specific image
processing and capture control algorithm optimized for common
image capture conditions.

Signed-off-by: HeungJun Kim <riverful.kim@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 Documentation/DocBook/media/v4l/controls.xml |  117 ++++++++++++++++++++++++++
 drivers/media/video/v4l2-ctrls.c             |   22 +++++
 include/linux/videodev2.h                    |   18 ++++
 3 files changed, 157 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index fc05f9d..5a3f78e 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3158,6 +3158,123 @@ requests.</entry>
 	  </row>
 	  <row><entry></entry></row>
 
+	  <row id="v4l2-scene-mode">
+	    <entry spanname="id"><constant>V4L2_CID_SCENE_MODE</constant>&nbsp;</entry>
+	    <entry>enum&nbsp;v4l2_scene_mode</entry>
+	  </row><row><entry spanname="descr">This control allows to select
+scene programs as the camera automatic modes optimized for common shooting
+scenes. Within these modes the camera determines best exposure, aperture,
+focusing, light metering, white balance and equivalent sensitivity. The
+controls of those parameters are influenced by the scene mode control.
+An exact behaviour in each mode is subject to the camera specification.
+
+<para>When the scene mode feature is not used this control should be set to
+<constant>V4L2_SCENE_MODE_NONE</constant>, to make sure the other possibly
+related controls are accessible. The following scene programs are defined:
+</para>
+</entry>
+	  </row>
+	  <row>
+	    <entrytbl spanname="descr" cols="2">
+	      <tbody valign="top">
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_NONE</constant>&nbsp;</entry>
+		  <entry>The scene mode feature is disabled.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_BACKLIGHT</constant>&nbsp;</entry>
+		  <entry>Backlight. Compensates for dark shadows when light is
+		  coming from behind a subject, also by automatically turning
+		  on the flash.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_BEACH_SNOW</constant>&nbsp;</entry>
+		  <entry>Beach and snow. This mode compensates for all-white or
+bright scenes, which tend to look gray and low contrast, when camera's automatic
+exposure is based on an average scene brightness. To compensate, this mode
+automatically slightly overexposes the frames. The white balance may also be
+adjusted to compensate for the fact that reflected snow looks bluish rather
+than white.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_CANDLELIGHT</constant>&nbsp;</entry>
+		  <entry>Candle light. The camera generally raises the ISO
+sensitivity and lowers the shutter speed. This mode compensates for relatively
+close subject in the scene. The flash is disabled in order to preserve the
+ambiance of the light.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_DAWN_DUSK</constant>&nbsp;</entry>
+		  <entry>Dawn and dusk. Preserves the colours seen in low
+natural light before dusk and after down. The camera may turn off the flash,
+and automatically focus at inifinity. It will usually boost saturation and
+lower the shutter speed.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_FALL_COLORS</constant>&nbsp;</entry>
+		  <entry>Fall colors. Increases saturation and adjusts white
+balance for color enhancement. Pictures of autumn leaves get saturated reds
+and yellows.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_FIREWORKS</constant>&nbsp;</entry>
+		  <entry>Fireworks. Long exposure times are used to capture
+the expanding burst of light from a firework. The camera may invoke image
+stabilization.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_LANDSCAPE</constant>&nbsp;</entry>
+		  <entry>Landscape. The camera may choose a small aperture to
+provide deep depth of field and long exposure duration to help capture detail
+in dim light conditions. The focus is fixed at infinity. Suitable for distant
+and wide scenery.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_NIGHT</constant>&nbsp;</entry>
+		  <entry>Night, also known as Night Landscape. Designed for low
+light conditions, it preserves detail in the dark areas without blowing out bright
+objects. The camera generally sets itself to a medium-to-high ISO sensitivity,
+with a relatively long exposure time, and turns flash off. As such, there will be
+increased image noise and the possibility of blurred image.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_PARTY_INDOOR</constant>&nbsp;</entry>
+		  <entry>Party and indoor. Designed to capture indoor scenes
+that are lit by indoor background lighting as well as the flash. The camera
+usually increases ISO sensitivity, and adjusts exposure for the low light
+conditions.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_PORTRAIT</constant>&nbsp;</entry>
+		  <entry>Portrait. The camera adjusts the aperture so that the
+depth of field is reduced, which helps to isolate the subject against a smooth
+background. Most cameras recognize the presence of faces in the scene and focus
+on them. The color hue is adjusted to enhance skin tones. The intensity of the
+flash is often reduced.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_SPORTS</constant>&nbsp;</entry>
+		  <entry>Sports. Significantly increases ISO and uses a fast
+shutter speed to freeze motion of rapidly-moving subjects. Increased image
+noise may be seen in this mode.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_SUNSET</constant>&nbsp;</entry>
+		  <entry>Sunset. Preserves deep hues seen in sunsets and
+sunrises. It bumps up the saturation.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_SCENE_MODE_TEXT</constant>&nbsp;</entry>
+		  <entry>Text. It applies extra contrast and sharpness, it is
+typically a black-and-white mode optimized for readability. Automatic focus
+may be switched to close-up mode and this setting may also involve some
+lens-distortion correction.</entry>
+		</row>
+	      </tbody>
+	    </entrytbl>
+	  </row>
+	  <row><entry></entry></row>
+
 	</tbody>
       </tgroup>
     </table>
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index e037601..f1d1ff2 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -266,6 +266,24 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		"Shade",
 		NULL,
 	};
+
+	static const char * const scene_mode[] = {
+		"None",
+		"Backlight",
+		"Beach/Snow",
+		"Candle Light",
+		"Dusk/Dawn",
+		"Fall Colors",
+		"Fireworks",
+		"Landscape",
+		"Night",
+		"Party/Indoor",
+		"Portrait",
+		"Sports",
+		"Sunset",
+		"Text",
+		NULL,
+	};
 	static const char * const tune_preemphasis[] = {
 		"No Preemphasis",
 		"50 useconds",
@@ -443,6 +461,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		return colorfx;
 	case V4L2_CID_WHITE_BALANCE_PRESET:
 		return white_balance_preset;
+	case V4L2_CID_SCENE_MODE:
+		return scene_mode;
 	case V4L2_CID_TUNE_PREEMPHASIS:
 		return tune_preemphasis;
 	case V4L2_CID_FLASH_LED_MODE:
@@ -635,6 +655,7 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_ISO_SENSITIVITY:		return "ISO Sensitivity";
 	case V4L2_CID_ISO_SENSITIVITY_AUTO:	return "ISO Sensitivity, Auto";
 	case V4L2_CID_EXPOSURE_METERING:	return "Exposure, Metering Mode";
+	case V4L2_CID_SCENE_MODE:		return "Scene Mode";
 
 	/* FM Radio Modulator control */
 	/* Keep the order of the 'case's the same as in videodev2.h! */
@@ -776,6 +797,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
 	case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
 	case V4L2_CID_EXPOSURE_METERING:
+	case V4L2_CID_SCENE_MODE:
 		*type = V4L2_CTRL_TYPE_MENU;
 		break;
 	case V4L2_CID_RDS_TX_PS_NAME:
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 37ecd6a..a1fc9a8 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1754,6 +1754,24 @@ enum v4l2_exposure_metering_mode {
 	V4L2_EXPOSURE_METERING_SPOT		= 2,
 };
 
+#define V4L2_CID_SCENE_MODE			(V4L2_CID_CAMERA_CLASS_BASE+26)
+enum v4l2_scene_mode {
+	V4L2_SCENE_MODE_NONE			= 0,
+	V4L2_SCENE_MODE_BACKLIGHT		= 1,
+	V4L2_SCENE_MODE_BEACH_SNOW		= 2,
+	V4L2_SCENE_MODE_CANDLE_LIGHT		= 3,
+	V4L2_SCENE_MODE_DAWN_DUSK		= 4,
+	V4L2_SCENE_MODE_FALL_COLORS		= 5,
+	V4L2_SCENE_MODE_FIREWORKS		= 6,
+	V4L2_SCENE_MODE_LANDSCAPE		= 7,
+	V4L2_SCENE_MODE_NIGHT			= 8,
+	V4L2_SCENE_MODE_PARTY_INDOOR		= 9,
+	V4L2_SCENE_MODE_PORTRAIT		= 10,
+	V4L2_SCENE_MODE_SPORTS			= 11,
+	V4L2_SCENE_MODE_SUNSET			= 12,
+	V4L2_SCENE_MODE_TEXT			= 13,
+};
+
 /* FM Modulator class control IDs */
 #define V4L2_CID_FM_TX_CLASS_BASE		(V4L2_CTRL_CLASS_FM_TX | 0x900)
 #define V4L2_CID_FM_TX_CLASS			(V4L2_CTRL_CLASS_FM_TX | 1)
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 10/15] V4L: Add camera 3A lock control
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
                   ` (8 preceding siblings ...)
  2012-04-17 10:09 ` [PATCH 09/15] V4L: Add camera scene mode control Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 16:09   ` Sakari Ailus
  2012-04-17 10:09 ` [PATCH 11/15] V4L: Add auto focus targets to the selections API Sylwester Nawrocki
                   ` (4 subsequent siblings)
  14 siblings, 1 reply; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

The V4L2_CID_3A_LOCK bitmask control allows applications to pause
or resume the automatic exposure, focus and wite balance adjustments.
It can be used, for example, to lock the 3A adjustments right before
a still image is captured, for pre-focus, etc.
The applications can control each of the algorithms independently,
through a corresponding control bit, if driver allows that.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 Documentation/DocBook/media/v4l/controls.xml |   40 ++++++++++++++++++++++++++
 drivers/media/video/v4l2-ctrls.c             |    2 ++
 include/linux/videodev2.h                    |    5 ++++
 3 files changed, 47 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 5a3f78e..c0926c3 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3275,6 +3275,46 @@ lens-distortion correction.</entry>
 	  </row>
 	  <row><entry></entry></row>
 
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_3A_LOCK</constant></entry>
+	    <entry>bitmask</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">This control locks or unlocks the automatic
+exposure, white balance and focus. The automatic adjustments can be paused
+independently by setting the coresponding lock bit to 1. The camera then retains
+the relevant 3A settings, until the lock bit is cleared. The value of this
+control may be changed by other, exposure, white balance or focus controls. The
+following are bit mask definitions for locking each algorithm independently:
+</entry>
+	  </row>
+	  <row>
+	    <entrytbl spanname="descr" cols="2">
+	      <tbody valign="top">
+		<row>
+		  <entry><constant>V4L2_3A_LOCK_EXPOSURE</constant></entry>
+		  <entry>Automatic exposure adjustments lock.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_3A_LOCK_WHITE_BALANCE</constant></entry>
+		  <entry>Automatic white balance adjustments lock.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_3A_LOCK_FOCUS</constant></entry>
+		  <entry>Automatic focus adjustments lock.</entry>
+		</row>
+	      </tbody>
+	    </entrytbl>
+	  </row>
+	  <row><entry spanname="descr">
+When a particular algorithm is not enabled, drivers should ignore
+requests to lock it and should return no error. An example might be an
+application setting bit <constant>V4L2_3A_LOCK_WHITE_BALANCE</constant>
+when <constant>V4L2_CID_AUTO_WHITE_BALANCE</constant> control is set to
+<constant>FALSE</constant>.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
 	</tbody>
       </tgroup>
     </table>
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index f1d1ff2..e21f210 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -656,6 +656,7 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_ISO_SENSITIVITY_AUTO:	return "ISO Sensitivity, Auto";
 	case V4L2_CID_EXPOSURE_METERING:	return "Exposure, Metering Mode";
 	case V4L2_CID_SCENE_MODE:		return "Scene Mode";
+	case V4L2_CID_3A_LOCK:			return "3A Lock";
 
 	/* FM Radio Modulator control */
 	/* Keep the order of the 'case's the same as in videodev2.h! */
@@ -828,6 +829,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 		break;
 	case V4L2_CID_FLASH_FAULT:
 	case V4L2_CID_JPEG_ACTIVE_MARKER:
+	case V4L2_CID_3A_LOCK:
 		*type = V4L2_CTRL_TYPE_BITMASK;
 		break;
 	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index a1fc9a8..4a60d5f 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1772,6 +1772,11 @@ enum v4l2_scene_mode {
 	V4L2_SCENE_MODE_TEXT			= 13,
 };
 
+#define V4L2_CID_3A_LOCK			(V4L2_CID_CAMERA_CLASS_BASE+27)
+#define V4L2_3A_LOCK_EXPOSURE			(1 << 0)
+#define V4L2_3A_LOCK_WHITE_BALANCE		(1 << 1)
+#define V4L2_3A_LOCK_FOCUS			(1 << 2)
+
 /* FM Modulator class control IDs */
 #define V4L2_CID_FM_TX_CLASS_BASE		(V4L2_CTRL_CLASS_FM_TX | 0x900)
 #define V4L2_CID_FM_TX_CLASS			(V4L2_CTRL_CLASS_FM_TX | 1)
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 11/15] V4L: Add auto focus targets to the selections API
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
                   ` (9 preceding siblings ...)
  2012-04-17 10:09 ` [PATCH 10/15] V4L: Add camera 3A lock control Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 12/15] V4L: Add auto focus targets to the subdev " Sylwester Nawrocki
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

The camera automatic focus algorithms may require setting up
a spot or rectangle coordinates or multiple such parameters.

The automatic focus selection targets are introduced in order
to allow applications to query and set such coordinates. Those
selections are intended to be used together with the automatic
focus controls available in the camera control class.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 Documentation/DocBook/media/v4l/selection-api.xml  |   33 +++++++++++++++++++-
 .../DocBook/media/v4l/vidioc-g-selection.xml       |   11 +++++++
 include/linux/videodev2.h                          |    5 +++
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/Documentation/DocBook/media/v4l/selection-api.xml b/Documentation/DocBook/media/v4l/selection-api.xml
index b299e47..490d29a 100644
--- a/Documentation/DocBook/media/v4l/selection-api.xml
+++ b/Documentation/DocBook/media/v4l/selection-api.xml
@@ -1,6 +1,6 @@
 <section id="selection-api">
 
-  <title>Experimental API for cropping, composing and scaling</title>
+  <title>Experimental selections API</title>
 
       <note>
 	<title>Experimental</title>
@@ -9,6 +9,10 @@
 interface and may change in the future.</para>
       </note>
 
+ <section>
+
+ <title>Image cropping, composing and scaling</title>
+
   <section>
     <title>Introduction</title>
 
@@ -321,5 +325,32 @@ V4L2_BUF_TYPE_VIDEO_OUTPUT </constant> for other devices</para>
       </example>
 
    </section>
+ </section>
+
+   <section>
+     <title>Automatic focus regions of interest</title>
+
+<para> The camera automatic focus algorithms may require configuration of
+regions of interest in form of rectangle or spot coordinates. The automatic
+focus selection targets allow applications to query and set such coordinates.
+Those selections are intended to be used together with the
+<constant>V4L2_CID_AUTO_FOCUS_AREA</constant> <link linkend="camera-controls">
+camera class</link> control. The <constant>V4L2_SEL_TGT_AUTO_FOCUS_ACTUAL
+</constant> target is used for querying or setting actual spot or rectangle
+coordinates, while <constant>V4L2_SEL_TGT_AUTO_FOCUS_BOUNDS</constant> target
+determines bounds for a single spot or rectangle.
+These selections are only effective when the <constant>V4L2_CID_AUTO_FOCUS_AREA
+</constant>control is set to <constant>V4L2_AUTO_FOCUS_AREA_SPOT</constant> or
+<constant>V4L2_AUTO_FOCUS_AREA_RECTANGLE</constant>. The new coordinates shall
+be accepted and applied to hardware when the focus area control value is
+changed and also during a &VIDIOC-S-SELECTION; ioctl call, only when the focus
+area control is already set to required value.</para>
+
+<para> For the <constant>V4L2_AUTO_FOCUS_AREA_SPOT</constant> case, the selection
+rectangle <structfield> width</structfield> and <structfield>height</structfield>
+are not used, i.e. shall be set to 0 by applications and ignored by drivers for
+the &VIDIOC-S-SELECTION; ioctl and shall be ignored by applications for the
+&VIDIOC-G-SELECTION; ioctl.</para>
+   </section>
 
 </section>
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-selection.xml b/Documentation/DocBook/media/v4l/vidioc-g-selection.xml
index bb04eff..87df4da 100644
--- a/Documentation/DocBook/media/v4l/vidioc-g-selection.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-g-selection.xml
@@ -195,6 +195,17 @@ exist no rectangle </emphasis> that satisfies the constraints.</para>
             <entry>0x0103</entry>
             <entry>The active area and all padding pixels that are inserted or modified by hardware.</entry>
 	  </row>
+	  <row>
+            <entry><constant>V4L2_SEL_TGT_AUTO_FOCUS_ACTUAL</constant></entry>
+            <entry>0x1000</entry>
+	    <entry>Actual automatic focus rectangle or spot coordinates.</entry>
+	  </row>
+	  <row>
+            <entry><constant>V4L2_SEL_TGT_AUTO_FOCUS_BOUNDS</constant></entry>
+            <entry>0x1002</entry>
+            <entry>Bounds of the automatic focus region of interest.
+	    </entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 4a60d5f..e6f69df 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -805,6 +805,11 @@ struct v4l2_crop {
 /* Current composing area plus all padding pixels */
 #define V4L2_SEL_TGT_COMPOSE_PADDED	0x0103
 
+/* Auto focus region of interest */
+#define V4L2_SEL_TGT_AUTO_FOCUS_ACTUAL	0x1000
+/* Auto focus region (spot coordinates) bounds */
+#define V4L2_SEL_TGT_AUTO_FOCUS_BOUNDS	0x1001
+
 /**
  * struct v4l2_selection - selection info
  * @type:	buffer type (do not use *_MPLANE types)
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 12/15] V4L: Add auto focus targets to the subdev selections API
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
                   ` (10 preceding siblings ...)
  2012-04-17 10:09 ` [PATCH 11/15] V4L: Add auto focus targets to the selections API Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 13/15] V4L: Add camera auto focus controls Sylwester Nawrocki
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 Documentation/DocBook/media/v4l/dev-subdev.xml     |   27 +++++++++++++++++++-
 .../media/v4l/vidioc-subdev-g-selection.xml        |   14 ++++++++--
 include/linux/v4l2-subdev.h                        |    4 +++
 3 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/dev-subdev.xml b/Documentation/DocBook/media/v4l/dev-subdev.xml
index 4afcbbe..8a212c4 100644
--- a/Documentation/DocBook/media/v4l/dev-subdev.xml
+++ b/Documentation/DocBook/media/v4l/dev-subdev.xml
@@ -277,7 +277,7 @@
     </section>
 
     <section>
-      <title>Selections: cropping, scaling and composition</title>
+      <title>Selections - cropping, scaling and composition</title>
 
       <para>Many sub-devices support cropping frames on their input or output
       pads (or possible even on both). Cropping is used to select the area of
@@ -330,6 +330,31 @@
     </section>
 
     <section>
+      <title>Selections - regions of interest</title>
+    <section>
+      <title>Automatic focus</title>
+
+      <para>The camera automatic focus algorithms may require configuration
+      of a region or multiple regions of interest in form of rectangle or spot
+      coordinates.</para>
+
+      <para>A single rectangle of interest is represented in &v4l2-rect;
+      by the coordinates of the top left corner and the rectangle size. Both
+      the coordinates and sizes are expressed in pixels. When the <structfield>
+      width</structfield> and <structfield>height</structfield> fields of
+      &v4l2-rect; are set to 0 the selection determines spot coordinates,
+      rather than a rectangle.</para>
+
+      <para>Auto focus rectangles are reset to their default values when the
+      output image format is modified. Drivers should use the output image size
+      as the auto focus rectangle default value, but hardware requirements may
+      prevent this.
+      </para>
+      <para>The auto focus selections on input pads are not defined.</para>
+    </section>
+    </section>
+
+    <section>
       <title>Types of selection targets</title>
 
       <section>
diff --git a/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml b/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
index 208e9f0..c4ccae5 100644
--- a/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
+++ b/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
@@ -57,8 +57,8 @@
 
     <para>The selections are used to configure various image
     processing functionality performed by the subdevs which affect the
-    image size. This currently includes cropping, scaling and
-    composition.</para>
+    image size. This currently includes cropping, scaling, composition
+    and automatic focus regions of interest.</para>
 
     <para>The selection API replaces <link
     linkend="vidioc-subdev-g-crop">the old subdev crop API</link>. All
@@ -114,6 +114,16 @@
 	    <entry>0x0102</entry>
 	    <entry>Bounds of the compose rectangle.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_TGT_AUTO_FOCUS_BOUNDS</constant></entry>
+	    <entry>0x1000</entry>
+	    <entry>Bounds of the automatic focus region of interest.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_TGT_AUTO_FOCUS_ACTUAL</constant></entry>
+	    <entry>0x1001</entry>
+	    <entry>Actual automatic focus rectangle or spot coordinates.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
diff --git a/include/linux/v4l2-subdev.h b/include/linux/v4l2-subdev.h
index 812019e..49b1f14 100644
--- a/include/linux/v4l2-subdev.h
+++ b/include/linux/v4l2-subdev.h
@@ -136,6 +136,10 @@ struct v4l2_subdev_frame_interval_enum {
 /* composing bounds */
 #define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS		0x0102
 
+/* auto focus region of interest */
+#define V4L2_SUBDEV_SEL_TGT_AUTO_FOCUS_ACTUAL		0x1000
+/* auto focus region (spot coordinates) bounds */
+#define V4L2_SUBDEV_SEL_TGT_AUTO_FOCUS_BOUNDS		0x1001
 
 /**
  * struct v4l2_subdev_selection - selection info
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 13/15] V4L: Add camera auto focus controls
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
                   ` (11 preceding siblings ...)
  2012-04-17 10:09 ` [PATCH 12/15] V4L: Add auto focus targets to the subdev " Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 14/15] V4L: Add S5C73M3 sensor sub-device driver Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 15/15] vivi: Add controls Sylwester Nawrocki
  14 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

Add following auto focus controls:

 - V4L2_CID_AUTO_FOCUS_START - single-shot auto focus start
 - V4L2_CID_AUTO_FOCUS_STOP -  single-shot auto focus stop
 - V4L2_CID_AUTO_FOCUS_STATUS - automatic focus status
 - V4L2_CID_AUTO_FOCUS_AREA - automatic focus area selection
 - V4L2_CID_AUTO_FOCUS_DISTANCE - automatic focus scan range selection

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 Documentation/DocBook/media/v4l/controls.xml |  140 +++++++++++++++++++++++++-
 drivers/media/video/v4l2-ctrls.c             |   26 ++++-
 include/linux/videodev2.h                    |   23 +++++
 3 files changed, 186 insertions(+), 3 deletions(-)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index c0926c3..b0c29e9 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -2967,13 +2967,149 @@ negative values towards infinity. This is a write-only control.</entry>
 	  <row>
 	    <entry spanname="id"><constant>V4L2_CID_FOCUS_AUTO</constant>&nbsp;</entry>
 	    <entry>boolean</entry>
-	  </row><row><entry spanname="descr">Enables automatic focus
-adjustments. The effect of manual focus adjustments while this feature
+	  </row><row><entry spanname="descr">Enables continuous automatic
+focus adjustments. The effect of manual focus adjustments while this feature
 is enabled is undefined, drivers should ignore such requests.</entry>
 	  </row>
 	  <row><entry></entry></row>
 
 	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_AUTO_FOCUS_START</constant>&nbsp;</entry>
+	    <entry>button</entry>
+	  </row><row><entry spanname="descr">Starts single auto focus process.
+The effect of setting this control when <constant>V4L2_CID_FOCUS_AUTO</constant>
+is set to <constant>TRUE</constant> (1) is undefined, drivers should ignore
+such requests.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_AUTO_FOCUS_STOP</constant>&nbsp;</entry>
+	    <entry>button</entry>
+	  </row><row><entry spanname="descr">Aborts automatic focusing
+started with <constant>V4L2_CID_AUTO_FOCUS_START</constant> control. It is
+effective only when the continuous autofocus is disabled, that is when
+<constant>V4L2_CID_FOCUS_AUTO</constant> control is set to <constant>FALSE
+</constant> (0).</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row id="v4l2-auto-focus-status">
+	    <entry spanname="id">
+	      <constant>V4L2_CID_AUTO_FOCUS_STATUS</constant>&nbsp;</entry>
+	    <entry>bitmask</entry>
+	  </row>
+	  <row><entry spanname="descr">The automatic focus status. This is a read-only
+	  control.</entry>
+	  </row>
+	  <row>
+	    <entrytbl spanname="descr" cols="2">
+	      <tbody valign="top">
+		<row>
+		  <entry><constant>V4L2_AUTO_FOCUS_STATUS_IDLE</constant>&nbsp;</entry>
+		  <entry>Automatic focus is inactive.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_AUTO_FOCUS_STATUS_BUSY</constant>&nbsp;</entry>
+		  <entry>Automatic focusing is in progress and the focus is changing.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_AUTO_FOCUS_STATUS_SUCCESS</constant>&nbsp;</entry>
+		  <entry>Automatic focus has completed or is continued successfully.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_AUTO_FOCUS_STATUS_FAIL</constant>&nbsp;</entry>
+		  <entry>Automatic focus has failed, the driver will not transition
+		    from this state until another action is performed by an
+		    application.</entry>
+		</row>
+	      </tbody>
+	    </entrytbl>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row id="v4l2-auto-focus-distance">
+	    <entry spanname="id">
+	      <constant>V4L2_CID_AUTO_FOCUS_DISTANCE</constant>&nbsp;</entry>
+	    <entry>enum&nbsp;v4l2_auto_focus_distance</entry>
+	  </row>
+	  <row><entry spanname="descr">Determines auto focus distance range
+for which lens may be adjusted. </entry>
+	  </row>
+	  <row>
+	    <entrytbl spanname="descr" cols="2">
+	      <tbody valign="top">
+		<row>
+		  <entry><constant>V4L2_AUTO_FOCUS_DISTANCE_NORMAL</constant>&nbsp;</entry>
+		  <entry>The auto focus normal distance range. It is limited
+for best auto focus algorithm performance.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_AUTO_FOCUS_DISTANCE_MACRO</constant>&nbsp;</entry>
+		  <entry>Macro (close-up) auto focus. The camera will
+use minimum possible distance that it is capable of for auto focus.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_AUTO_FOCUS_DISTANCE_INFINITY</constant>&nbsp;</entry>
+		  <entry>The camera is focused permanently at its farthest
+possible distance.</entry>
+		</row>
+	      </tbody>
+	    </entrytbl>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row id="v4l2-auto-focus-area">
+	    <entry spanname="id">
+	      <constant>V4L2_CID_AUTO_FOCUS_AREA</constant>&nbsp;</entry>
+	    <entry>enum&nbsp;v4l2_auto_focus_area</entry>
+	  </row>
+	  <row><entry spanname="descr">Determines the area of the frame that
+the camera uses for automatic focus. The corresponding coordinates of the
+focusing spot or rectangle can be specified and queried using the selection API.
+To change the auto focus region of interest applications first select required
+mode of this control and then set the rectangle or spot coordinates by means
+of the &VIDIOC-SUBDEV-S-SELECTION; or &VIDIOC-S-SELECTION; ioctl. In order to
+trigger again an auto focus process with same coordinates applications should
+use the <constant>V4L2_CID_AUTO_FOCUS_START </constant> control. Or alternatively
+invoke a &VIDIOC-SUBDEV-S-SELECTION; or a &VIDIOC-S-SELECTION; ioctl again.
+In the latter case the new pixel coordinates are applied to hardware only when
+the focus area control is set to a value other than
+<constant>V4L2_AUTO_FOCUS_AREA_ALL</constant>.</entry>
+	  </row>
+	  <row>
+	    <entrytbl spanname="descr" cols="2">
+	      <tbody valign="top">
+		<row>
+		  <entry><constant>V4L2_AUTO_FOCUS_AREA_ALL</constant>&nbsp;</entry>
+		  <entry>Normal auto focus, the focusing area extends over the
+entire frame.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_AUTO_FOCUS_AREA_SPOT</constant>&nbsp;</entry>
+		  <entry>Automatic focus on a spot within the frame at position
+specified by the <constant>V4L2_SEL_TGT_AUTO_FOCUS_ACTUAL</constant> or
+<constant>V4L2_SUBDEV_SEL_TGT_AUTO_FOCUS_ACTUAL</constant> selection. When these
+selections are not supported by driver the default spot's position is center of
+the frame.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_AUTO_FOCUS_AREA_RECTANGLE</constant>&nbsp;</entry>
+		  <entry>The auto focus area is determined by the <constant>
+V4L2_SEL_TGT_AUTO_FOCUS_ACTUAL</constant> or <constant>
+V4L2_SUBDEV_SEL_TGT_AUTO_FOCUS_ACTUAL</constant> selection rectangle.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_AUTO_FOCUS_AREA_FACE_DETECTION</constant>&nbsp;</entry>
+		  <entry>The camera automatically focuses on a detected face
+area.</entry>
+		</row>
+	      </tbody>
+	    </entrytbl>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row>
 	    <entry spanname="id"><constant>V4L2_CID_ZOOM_ABSOLUTE</constant>&nbsp;</entry>
 	    <entry>integer</entry>
 	  </row><row><entry spanname="descr">Specify the objective lens
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index e21f210..84cde5f 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -236,6 +236,19 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		"Spot",
 		NULL
 	};
+	static const char * const camera_auto_focus_area[] = {
+		"All",
+		"Spot",
+		"Rectangle",
+		"Face Detection",
+		NULL
+	};
+	static const char * const camera_auto_focus_distance[] = {
+		"Normal",
+		"Macro",
+		"Infinity",
+		NULL
+	};
 	static const char * const colorfx[] = {
 		"None",
 		"Black & White",
@@ -641,7 +654,7 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_TILT_ABSOLUTE:		return "Tilt, Absolute";
 	case V4L2_CID_FOCUS_ABSOLUTE:		return "Focus, Absolute";
 	case V4L2_CID_FOCUS_RELATIVE:		return "Focus, Relative";
-	case V4L2_CID_FOCUS_AUTO:		return "Focus, Automatic";
+	case V4L2_CID_FOCUS_AUTO:		return "Focus, Automatic Continuous";
 	case V4L2_CID_ZOOM_ABSOLUTE:		return "Zoom, Absolute";
 	case V4L2_CID_ZOOM_RELATIVE:		return "Zoom, Relative";
 	case V4L2_CID_ZOOM_CONTINUOUS:		return "Zoom, Continuous";
@@ -657,6 +670,11 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_EXPOSURE_METERING:	return "Exposure, Metering Mode";
 	case V4L2_CID_SCENE_MODE:		return "Scene Mode";
 	case V4L2_CID_3A_LOCK:			return "3A Lock";
+	case V4L2_CID_AUTO_FOCUS_START:		return "Auto Focus, Start";
+	case V4L2_CID_AUTO_FOCUS_STOP:		return "Auto Focus, Stop";
+	case V4L2_CID_AUTO_FOCUS_STATUS:	return "Auto Focus, Status";
+	case V4L2_CID_AUTO_FOCUS_DISTANCE:	return "Auto Focus, Distance";
+	case V4L2_CID_AUTO_FOCUS_AREA:		return "Auto Focus, Area";
 
 	/* FM Radio Modulator control */
 	/* Keep the order of the 'case's the same as in videodev2.h! */
@@ -759,6 +777,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_TILT_RESET:
 	case V4L2_CID_FLASH_STROBE:
 	case V4L2_CID_FLASH_STROBE_STOP:
+	case V4L2_CID_AUTO_FOCUS_START:
+	case V4L2_CID_AUTO_FOCUS_STOP:
 		*type = V4L2_CTRL_TYPE_BUTTON;
 		*flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
 		*min = *max = *step = *def = 0;
@@ -782,6 +802,8 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_STREAM_TYPE:
 	case V4L2_CID_MPEG_STREAM_VBI_FMT:
 	case V4L2_CID_EXPOSURE_AUTO:
+	case V4L2_CID_AUTO_FOCUS_AREA:
+	case V4L2_CID_AUTO_FOCUS_DISTANCE:
 	case V4L2_CID_COLORFX:
 	case V4L2_CID_WHITE_BALANCE_PRESET:
 	case V4L2_CID_TUNE_PREEMPHASIS:
@@ -830,6 +852,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_FLASH_FAULT:
 	case V4L2_CID_JPEG_ACTIVE_MARKER:
 	case V4L2_CID_3A_LOCK:
+	case V4L2_CID_AUTO_FOCUS_STATUS:
 		*type = V4L2_CTRL_TYPE_BITMASK;
 		break;
 	case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
@@ -888,6 +911,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 		*flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
 		break;
 	case V4L2_CID_FLASH_STROBE_STATUS:
+	case V4L2_CID_AUTO_FOCUS_STATUS:
 	case V4L2_CID_FLASH_READY:
 		*flags |= V4L2_CTRL_FLAG_READ_ONLY;
 		break;
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index e6f69df..ea83e1a 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1782,6 +1782,29 @@ enum v4l2_scene_mode {
 #define V4L2_3A_LOCK_WHITE_BALANCE		(1 << 1)
 #define V4L2_3A_LOCK_FOCUS			(1 << 2)
 
+#define V4L2_CID_AUTO_FOCUS_START		(V4L2_CID_CAMERA_CLASS_BASE+28)
+#define V4L2_CID_AUTO_FOCUS_STOP		(V4L2_CID_CAMERA_CLASS_BASE+29)
+#define V4L2_CID_AUTO_FOCUS_STATUS		(V4L2_CID_CAMERA_CLASS_BASE+30)
+#define V4L2_AUTO_FOCUS_STATUS_IDLE		(0 << 0)
+#define V4L2_AUTO_FOCUS_STATUS_BUSY		(1 << 0)
+#define V4L2_AUTO_FOCUS_STATUS_SUCCESS		(1 << 1)
+#define V4L2_AUTO_FOCUS_STATUS_FAIL		(1 << 2)
+
+#define V4L2_CID_AUTO_FOCUS_DISTANCE		(V4L2_CID_CAMERA_CLASS_BASE+31)
+enum v4l2_auto_focus_distance {
+	V4L2_AUTO_FOCUS_DISTANCE_NORMAL		= 0,
+	V4L2_AUTO_FOCUS_DISTANCE_MACRO		= 1,
+	V4L2_AUTO_FOCUS_DISTANCE_INFINITY	= 2,
+};
+
+#define V4L2_CID_AUTO_FOCUS_AREA		(V4L2_CID_CAMERA_CLASS_BASE+32)
+enum v4l2_auto_focus_area {
+	V4L2_AUTO_FOCUS_AREA_ALL		= 0,
+	V4L2_AUTO_FOCUS_AREA_SPOT		= 1,
+	V4L2_AUTO_FOCUS_AREA_RECTANGLE		= 2,
+	V4L2_AUTO_FOCUS_AREA_FACE_DETECTION	= 3,
+};
+
 /* FM Modulator class control IDs */
 #define V4L2_CID_FM_TX_CLASS_BASE		(V4L2_CTRL_CLASS_FM_TX | 0x900)
 #define V4L2_CID_FM_TX_CLASS			(V4L2_CTRL_CLASS_FM_TX | 1)
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 14/15] V4L: Add S5C73M3 sensor sub-device driver
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
                   ` (12 preceding siblings ...)
  2012-04-17 10:09 ` [PATCH 13/15] V4L: Add camera auto focus controls Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  2012-04-17 10:09 ` [PATCH 15/15] vivi: Add controls Sylwester Nawrocki
  14 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

 - initial working version
 - public header cleanup
 - add SPI slave driver and FW upload support
 - firmware load cleanup
 - change SPI driver initialization method
 - move SPI driver to separate file
 - capture context control

This driver is a work in progress, it is included in this series
only to demonstrate how the new controls are used.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/media/video/Kconfig                 |    8 +
 drivers/media/video/Makefile                |    1 +
 drivers/media/video/s5c73m3/Makefile        |    3 +
 drivers/media/video/s5c73m3/s5c73m3-ctrls.c |  702 +++++++++++++++
 drivers/media/video/s5c73m3/s5c73m3-spi.c   |  126 +++
 drivers/media/video/s5c73m3/s5c73m3.c       | 1235 +++++++++++++++++++++++++++
 drivers/media/video/s5c73m3/s5c73m3.h       |  446 ++++++++++
 include/media/s5c73m3.h                     |   62 ++
 8 files changed, 2583 insertions(+)
 create mode 100644 drivers/media/video/s5c73m3/Makefile
 create mode 100644 drivers/media/video/s5c73m3/s5c73m3-ctrls.c
 create mode 100644 drivers/media/video/s5c73m3/s5c73m3-spi.c
 create mode 100644 drivers/media/video/s5c73m3/s5c73m3.c
 create mode 100644 drivers/media/video/s5c73m3/s5c73m3.h
 create mode 100644 include/media/s5c73m3.h

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 0680d91..4bc3df2 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -531,6 +531,14 @@ config VIDEO_S5K6AA
 	  This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
 	  camera sensor with an embedded SoC image signal processor.
 
+config VIDEO_S5C73M3
+	tristate "Samsung S5C73M3 sensor support (experimental)"
+	depends on I2C && SPI && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	depends on EXPERIMENTAL
+	---help---
+	  This is a V4L2 sensor-level driver for Samsung S5C73M3
+	  8 Mpixel camera.
+
 comment "Flash devices"
 
 config VIDEO_ADP1653
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 6400487..e9cf433 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -73,6 +73,7 @@ obj-$(CONFIG_VIDEO_SR030PC30)	+= sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)	+= noon010pc30.o
 obj-$(CONFIG_VIDEO_M5MOLS)	+= m5mols/
 obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
+obj-$(CONFIG_VIDEO_S5C73M3)	+= s5c73m3/
 obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
 obj-$(CONFIG_VIDEO_AS3645A)	+= as3645a.o
 
diff --git a/drivers/media/video/s5c73m3/Makefile b/drivers/media/video/s5c73m3/Makefile
new file mode 100644
index 0000000..c8a0a40
--- /dev/null
+++ b/drivers/media/video/s5c73m3/Makefile
@@ -0,0 +1,3 @@
+# Makefile for S5C73M3 camera driver
+
+obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3.o s5c73m3-spi.o s5c73m3-ctrls.o
diff --git a/drivers/media/video/s5c73m3/s5c73m3-ctrls.c b/drivers/media/video/s5c73m3/s5c73m3-ctrls.c
new file mode 100644
index 0000000..1cc6065
--- /dev/null
+++ b/drivers/media/video/s5c73m3/s5c73m3-ctrls.c
@@ -0,0 +1,702 @@
+/*
+ * Samsung LSI S5C73M3 8M pixel camera driver
+ *
+ * Copyright (C) 2012, Samsung Electronics, Co., Ltd.
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
+
+#include <asm/sizes.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/media.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/videodev2.h>
+#include <media/media-entity.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-mediabus.h>
+#include <media/s5c73m3.h>
+
+#include "s5c73m3.h"
+
+static int s5c73m3_get_af_status(struct s5c73m3 *state, struct v4l2_ctrl *ctrl)
+{
+	u16 reg = REG_AF_STATUS_UNFOCUSED;
+
+	int err = s5c73m3_read(state->i2c_client, REG_AF_STATUS, &reg);
+	/*err = s5c73m3_read(sd, 0x0009, 0x5840, &temp_status);*/
+
+	switch (reg) {
+	case REG_CAF_STATUS_FIND_SEARCH_DIR:
+	case REG_AF_STATUS_FOCUSING:
+	case REG_CAF_STATUS_FOCUSING:
+	case REG_AF_STATUS_INVALID:
+		ctrl->val = V4L2_AUTO_FOCUS_STATUS_BUSY;
+		break;
+
+	case REG_CAF_STATUS_FOCUSED:
+	case REG_AF_STATUS_FOCUSED:
+		ctrl->val = V4L2_AUTO_FOCUS_STATUS_SUCCESS;
+		break;
+
+	default:
+		v4l2_info(&state->subdev, "Unknown AF status\n");
+		/* Fall through */
+	case REG_CAF_STATUS_UNFOCUSED:
+	case REG_AF_STATUS_UNFOCUSED:
+		ctrl->val = V4L2_AUTO_FOCUS_STATUS_FAIL;
+		break;
+	}
+
+	return err;
+}
+
+static int s5c73m3_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	int err;
+
+	v4l2_dbg(1, s5c73m3_dbg, sd, "%s: ctrl: %s\n", __func__, ctrl->name);
+
+	if (state->power == 0)
+		return -EBUSY;
+
+	switch (ctrl->id) {
+	case V4L2_CID_FIRMWARE_VERSION:
+		/* FIXME: */
+		/* strlcpy(ctrl->string, state->exif.unique_id, ctrl->maximum); */
+		break;
+
+	case V4L2_CID_FOCUS_AUTO:
+		err = s5c73m3_get_af_status(state, state->ctrls.af_status);
+		if (err)
+			return err;
+		v4l2_dbg(1, s5c73m3_dbg, sd, "AF status: %#x\n",
+			 state->ctrls.af_status->val);
+		break;
+	}
+
+	return 0;
+}
+
+static int s5c73m3_set_colorfx(struct s5c73m3 *state, int val)
+{
+	static const unsigned short colorfx[][2] = {
+		{ V4L2_COLORFX_NONE,	 REG_IMAGE_EFFECT_NONE },
+		{ V4L2_COLORFX_BW,	 REG_IMAGE_EFFECT_MONO },
+		{ V4L2_COLORFX_SEPIA,	 REG_IMAGE_EFFECT_SEPIA },
+		{ V4L2_COLORFX_NEGATIVE, REG_IMAGE_EFFECT_NEGATIVE },
+		{ V4L2_COLORFX_AQUA,	 REG_IMAGE_EFFECT_AQUA },
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(colorfx); i++) {
+		if (colorfx[i][0] != val)
+			continue;
+
+		v4l2_dbg(1, s5c73m3_dbg, &state->subdev,
+			 "Setting %s color effect\n",
+			 v4l2_ctrl_get_menu(state->ctrls.colorfx->id)[i]);
+
+		return s5c73m3_write_cmd(state, REG_IMAGE_EFFECT,
+					 colorfx[i][1]);
+	}
+	return -EINVAL;
+}
+
+/* Set exposure metering/exposure bias */
+static int s5c73m3_set_exposure(struct s5c73m3 *state, int auto_exp)
+{
+	struct v4l2_subdev *sd = &state->subdev;
+	struct s5c73m3_ctrls *ctrls = &state->ctrls;
+	int err = 0;
+
+	if (ctrls->exposure_metering->is_new) {
+		u16 metering;
+
+		switch (ctrls->exposure_metering->val) {
+		case V4L2_EXPOSURE_METERING_CENTER_WEIGHTED:
+			metering = REG_METERING_CENTER;
+			break;
+		case V4L2_EXPOSURE_METERING_SPOT:
+			metering = REG_METERING_SPOT;
+			break;
+		default:
+			metering = REG_METERING_AVERAGE;
+			break;
+		}
+
+		err = s5c73m3_write_cmd(state, REG_METERING, metering);
+	}
+
+	if (!err && ctrls->exposure_bias->is_new) {
+		u16 exp_bias = ctrls->exposure_bias->val;
+		err = s5c73m3_write_cmd(state, REG_EV, exp_bias);
+	}
+
+	v4l2_dbg(1, s5c73m3_dbg, sd,
+		 "%s: exposure bias: %#x, metering: %#x (%d)\n",  __func__,
+		 ctrls->exposure_bias->val, ctrls->exposure_metering->val, err);
+
+	return err;
+}
+
+static int s5c73m3_set_white_balance(struct s5c73m3 *state, int awb)
+{
+	u16 wb = REG_AWB_MODE_AUTO;
+
+	if (!awb) {
+		switch (state->ctrls.wb_preset->val) {
+		case V4L2_WHITE_BALANCE_PRESET_INCANDESCENT:
+			wb = REG_AWB_MODE_INCANDESCENT;
+			break;
+		case V4L2_WHITE_BALANCE_PRESET_FLUORESCENT:
+			wb = REG_AWB_MODE_FLUORESCENT1;
+			break;
+		case V4L2_WHITE_BALANCE_PRESET_CLOUDY:
+			wb = REG_AWB_MODE_CLOUDY;
+			break;
+		case V4L2_WHITE_BALANCE_PRESET_DAYLIGHT:
+		default:
+			wb = REG_AWB_MODE_DAYLIGHT;
+			break;
+		}
+	}
+
+	return s5c73m3_write_cmd(state, REG_AWB_MODE, wb);
+}
+
+static int s5c73m3_3a_lock(struct s5c73m3 *state, struct v4l2_ctrl *ctrl)
+{
+	bool awb_lock = ctrl->val & V4L2_3A_LOCK_WHITE_BALANCE;
+	bool ae_lock = ctrl->val & V4L2_3A_LOCK_EXPOSURE;
+	int err = 0;
+
+	if ((ctrl->val ^ ctrl->cur.val) & V4L2_3A_LOCK_EXPOSURE) {
+		err = s5c73m3_write_cmd(state, REG_AE_CON,
+				ae_lock ? REG_AE_STOP : REG_AE_START);
+		if (err)
+			return err;
+	}
+
+	if (((ctrl->val ^ ctrl->cur.val) & V4L2_3A_LOCK_WHITE_BALANCE)
+	    && state->ctrls.auto_wb->val) {
+		err = s5c73m3_write_cmd(state, REG_AWB_CON,
+			awb_lock ? REG_AWB_STOP : REG_AWB_START);
+	}
+
+	return err;
+}
+
+/* TODO: focus untested */
+
+static int s5c73m3_set_touch_auto_focus(struct s5c73m3 *state)
+{
+	struct v4l2_mbus_framefmt *mf = &state->format[PREVIEW_IDX];
+	struct i2c_client *client = state->i2c_client;
+	int err;
+
+	err = s5c73m3_i2c_write(client, 0xfcfc, 0x3310);
+	if (!err)
+		err = s5c73m3_i2c_write(client, 0x0050, 0x0009);
+	if (!err)
+		err = s5c73m3_i2c_write(client, 0x0054, REG_AF_TOUCH_POSITION);
+	if (!err)
+		err = s5c73m3_i2c_write(client, 0x0f14, state->focus.pos_x);
+	if (!err)
+		err = s5c73m3_i2c_write(client, 0x0f14, state->focus.pos_y);
+	/* FIXME: Find out what this width/height is really for */
+	if (!err)
+		err = s5c73m3_i2c_write(client, 0x0f14, mf->width);
+	if (!err)
+		err = s5c73m3_i2c_write(client, 0x0f14, mf->height);
+	if (!err)
+		err = s5c73m3_i2c_write(client, 0x0050, 0x0009);
+	if (!err)
+		err = s5c73m3_i2c_write(client, 0x0054, 0x5000);
+	if (!err)
+		err = s5c73m3_i2c_write(client, 0x0f14, 0x0e0a);
+	if (!err)
+		err = s5c73m3_i2c_write(client, 0x0f14, 0x0000);
+	if (!err)
+		err = s5c73m3_i2c_write(client, 0x0054, 0x5080);
+	if (!err)
+		err = s5c73m3_i2c_write(client, 0x0f14, 0x0001);
+
+	return err;
+}
+
+static int s5c73m3_set_auto_focus(struct s5c73m3 *state, int caf)
+{
+	struct v4l2_subdev *sd = &state->subdev;
+	struct s5c73m3_ctrls *ctrls = &state->ctrls;
+	u8 af_mode = 0;
+	int err = 0;
+
+	if (ctrls->af_distance->is_new) {
+		switch (ctrls->af_distance->val) {
+		case V4L2_AUTO_FOCUS_DISTANCE_MACRO:
+			af_mode = 0;
+			break;
+		case V4L2_AUTO_FOCUS_DISTANCE_INFINITY:
+			af_mode = 0;
+			break;
+		case V4L2_AUTO_FOCUS_DISTANCE_NORMAL:
+			af_mode = 0;
+			break;
+		}
+	}
+
+	if (ctrls->af_area->is_new) {
+		if (ctrls->af_area->val == V4L2_AUTO_FOCUS_AREA_SPOT) {
+			v4l2_ctrl_activate(ctrls->af_distance, 0);
+			af_mode = 0;
+		} else {
+			/*
+			 * Activate the auto focus distance control only if
+			 * auto focus area is set to V4L2_AUTO_FOCUS_AREA_ALL
+			 */
+			v4l2_ctrl_activate(ctrls->af_distance, 1);
+		}
+	}
+
+	v4l2_dbg(1, s5c73m3_dbg, sd, "af_mode: %#x\n", af_mode);
+
+	if (ctrls->af_area->val == V4L2_AUTO_FOCUS_AREA_SPOT) {
+		err = s5c73m3_set_touch_auto_focus(state);
+		if (err < 0)
+			return err;
+
+		v4l2_dbg(1, s5c73m3_dbg, sd, "Focus position: x: %u, y: %u\n",
+			state->focus.pos_x, state->focus.pos_y);
+	}
+
+	if (ctrls->af_stop->is_new) {
+		err = 0;
+		if (err < 0)
+			return err;
+		v4l2_dbg(1, s5c73m3_dbg, sd, "Auto focus stopped\n");
+	}
+
+	if (ctrls->af_start->is_new || ctrls->focus_auto->is_new) {
+		/* Start continuous or one-shot auto focusing */
+		err = 0;
+		v4l2_dbg(1, s5c73m3_dbg, sd, "%s auto focus started\n",
+			 caf ? "Continuous" : "One-shot");
+	}
+
+	v4l2_dbg(1, s5c73m3_dbg, sd, "af_mode: %#x (%d)\n", af_mode, err);
+
+	return err;
+}
+
+static int s5c73m3_set_contrast(struct s5c73m3 *state, int val)
+{
+	u16 reg = (val < 0) ? -val + 2 : val;
+	return s5c73m3_write_cmd(state, REG_CONTRAST, reg);
+}
+
+static int s5c73m3_set_saturation(struct s5c73m3 *state, int val)
+{
+	u16 reg = (val < 0) ? -val + 2 : val;
+	return s5c73m3_write_cmd(state, REG_SATURATION, reg);
+}
+
+static int s5c73m3_set_sharpness(struct s5c73m3 *state, int val)
+{
+	u16 reg = (val < 0) ? -val + 2 : val;
+	return s5c73m3_write_cmd(state, REG_SHARPNESS, reg);
+}
+
+static int s5c73m3_set_iso(struct s5c73m3 *state, int iso_auto)
+{
+	u32 iso = iso_auto ? 0 : state->ctrls.iso->val + 1;
+	return s5c73m3_write_cmd(state, REG_ISO, iso);
+}
+
+static int s5c73m3_set_stabilization(struct s5c73m3 *state, int val)
+{
+	struct v4l2_subdev *sd = &state->subdev;
+
+	v4l2_dbg(1, s5c73m3_dbg, sd, "Image stabilization: %d\n", val);
+
+	return s5c73m3_write_cmd(state, REG_AE_MODE, val  ?
+				 REG_AE_MODE_ANTI_SHAKE : REG_AE_MODE_AUTO_SET);
+}
+
+static int s5c73m3_set_still_capture(struct s5c73m3 *state, int on)
+{
+	return 0;
+}
+
+static int s5c73m3_set_jpeg_quality(struct s5c73m3 *state, int quality)
+{
+	int reg;
+
+	if (quality <= 65)
+		reg = REG_IMAGE_QUALITY_NORMAL;
+	else if (quality <= 75)
+		reg = REG_IMAGE_QUALITY_FINE;
+	else
+		reg = REG_IMAGE_QUALITY_SUPERFINE;
+
+	return s5c73m3_write_cmd(state, REG_IMAGE_QUALITY, reg);
+}
+
+static int s5c73m3_set_flash(struct s5c73m3 *state, int val)
+{
+	int err, flash;
+
+	switch (val) {
+	case FLASH_MODE_AUTO:
+		flash = REG_FLASH_MODE_AUTO;
+		break;
+	case FLASH_MODE_ON:
+		flash = REG_FLASH_MODE_ON;
+		break;
+	default:
+		flash = REG_FLASH_MODE_OFF;
+		break;
+	}
+
+	err = s5c73m3_write_cmd(state, REG_FLASH_MODE, flash);
+	if (err)
+		return err;
+	return s5c73m3_write_cmd(state, REG_FLASH_TORCH,
+				 val == FLASH_MODE_TORCH);
+}
+
+static int s5c73m3_set_scene_program(struct s5c73m3 *state, int val)
+{
+	static const unsigned short scene_lookup[][2] = {
+		{ V4L2_SCENE_MODE_NONE,		REG_SCENE_MODE_NONE },
+		{ V4L2_SCENE_MODE_BACKLIGHT,	REG_SCENE_MODE_AGAINST_LIGHT },
+		{ V4L2_SCENE_MODE_BEACH_SNOW,	REG_SCENE_MODE_BEACH },
+		{ V4L2_SCENE_MODE_CANDLE_LIGHT,	REG_SCENE_MODE_CANDLE },
+		{ V4L2_SCENE_MODE_DAWN_DUSK,	REG_SCENE_MODE_DAWN },
+		{ V4L2_SCENE_MODE_FALL_COLORS,	REG_SCENE_MODE_FALL },
+		{ V4L2_SCENE_MODE_FIREWORKS,	REG_SCENE_MODE_FIRE },
+		{ V4L2_SCENE_MODE_LANDSCAPE,	REG_SCENE_MODE_LANDSCAPE },
+		{ V4L2_SCENE_MODE_NIGHT,	REG_SCENE_MODE_NIGHT },
+		{ V4L2_SCENE_MODE_PARTY_INDOOR,	REG_SCENE_MODE_INDOOR },
+		{ V4L2_SCENE_MODE_PORTRAIT,	REG_SCENE_MODE_PORTRAIT },
+		{ V4L2_SCENE_MODE_SPORTS,	REG_SCENE_MODE_SPORTS },
+		{ V4L2_SCENE_MODE_SUNSET,	REG_SCENE_MODE_SUNSET },
+		{ V4L2_SCENE_MODE_TEXT,		REG_SCENE_MODE_TEXT },
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(scene_lookup); i++) {
+		if (scene_lookup[i][0] != val)
+			continue;
+
+		v4l2_dbg(1, s5c73m3_dbg, &state->subdev,
+			 "Setting %s scene program\n",
+			 v4l2_ctrl_get_menu(state->ctrls.scene_mode->id)[i]);
+
+		return s5c73m3_write_cmd(state, REG_SCENE_MODE,
+					 scene_lookup[i][1]);
+	}
+
+	return -EINVAL;
+}
+
+static int s5c73m3_s_ctrl(struct v4l2_ctrl *ctrl)
+{
+	struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
+	/* struct i2c_client *client = v4l2_get_subdevdata(sd); */
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	int err = 0;
+
+	v4l2_dbg(1, s5c73m3_dbg, sd, "ctrl: 0x%x, value: %d\n",
+		 ctrl->id, ctrl->val);
+
+	/* mutex_lock(&state->lock); */
+	/*
+	 * If the device is not powered up by the host driver do
+	 * not apply any controls to H/W at this time. Instead
+	 * the controls will be restored right after power-up.
+	 */
+	if (state->power == 0)
+		goto unlock;
+
+	if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE)
+		return -EINVAL;
+
+	switch (ctrl->id) {
+	case V4L2_CID_3A_LOCK:
+		err = s5c73m3_3a_lock(state, ctrl);
+		break;
+
+	case V4L2_CID_AUTO_WHITE_BALANCE:
+		err = s5c73m3_set_white_balance(state, ctrl->val);
+		break;
+
+	case V4L2_CID_CONTRAST:
+		err = s5c73m3_set_contrast(state, ctrl->val);
+		break;
+
+	case V4L2_CID_COLORFX:
+		err = s5c73m3_set_colorfx(state, ctrl->val);
+		break;
+
+	case V4L2_CID_EXPOSURE_AUTO:
+		err = s5c73m3_set_exposure(state, ctrl->val);
+		break;
+
+	case V4L2_CID_FLASH_MODE:
+		err = s5c73m3_set_flash(state, ctrl->val);
+		break;
+
+	case V4L2_CID_FOCUS_AUTO:
+		err = s5c73m3_set_auto_focus(state, ctrl->val);
+		break;
+
+	case V4L2_CID_IMAGE_STABILIZATION:
+		err = s5c73m3_set_stabilization(state, ctrl->val);
+		break;
+
+	case V4L2_CID_ISO_SENSITIVITY:
+		err = s5c73m3_set_iso(state, ctrl->val);
+		break;
+
+	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
+		err = s5c73m3_set_jpeg_quality(state, ctrl->val);
+		break;
+
+	case V4L2_CID_POWER_LINE_FREQUENCY:
+		/* err = s5c73m3_set_anti_flicker(state, ctrl->val); */
+		break;
+
+	case V4L2_CID_SATURATION:
+		err = s5c73m3_set_saturation(state, ctrl->val);
+		break;
+
+	case V4L2_CID_SCENE_MODE:
+		err = s5c73m3_set_scene_program(state, ctrl->val);
+		break;
+
+	case V4L2_CID_SHARPNESS:
+		err = s5c73m3_set_sharpness(state, ctrl->val);
+		break;
+
+	case V4L2_CID_SNAPSHOT:
+		err = s5c73m3_set_still_capture(state, ctrl->val);
+		break;
+
+	case V4L2_CID_WIDE_DYNAMIC_RANGE:
+		err = s5c73m3_write_cmd(state, REG_WDR, ctrl->val);
+		break;
+
+	case V4L2_CID_ZOOM_ABSOLUTE:
+		err = s5c73m3_write_cmd(state, REG_ZOOM_STEP, ctrl->val);
+		break;
+	}
+unlock:
+	/* mutex_unlock(&state->lock); */
+	return err;
+}
+
+static const struct v4l2_ctrl_ops s5c73m3_ctrl_ops = {
+	.g_volatile_ctrl	= s5c73m3_g_volatile_ctrl,
+	.s_ctrl			= s5c73m3_s_ctrl,
+};
+
+static const char * const s5c73m3_flash_mode_menu[] = {
+	"Off", "Auto", "On", "Torch",
+};
+
+static const char * const s5c73m3_capture_ctx_menu[] = {
+	"Preview", "Still", "Camcorder",
+};
+
+static const struct v4l2_ctrl_config s5c73m3_ctrls[] = {
+	[0] = {
+		.ops = &s5c73m3_ctrl_ops,
+		.id = V4L2_CID_FIRMWARE_VERSION,
+		.type = V4L2_CTRL_TYPE_STRING,
+		.name = "Firmware version",
+		.min = 2,
+		.max = 128,
+		.step = 1,
+	},
+	[1] = {
+		.ops = &s5c73m3_ctrl_ops,
+		.id = V4L2_CID_CAPTURE_CTX,
+		.type = V4L2_CTRL_TYPE_MENU,
+		.name = "Capture Context",
+		.max = ARRAY_SIZE(s5c73m3_capture_ctx_menu) - 1,
+		.qmenu = s5c73m3_capture_ctx_menu,
+		.def = V4L2_CAPTURE_CTX_PREVIEW,
+	},
+	[2] = {
+		.ops = &s5c73m3_ctrl_ops,
+		.id = V4L2_CID_SNAPSHOT,
+		.type = V4L2_CTRL_TYPE_BOOLEAN,
+		.name = "Snapshot",
+		.max = 1,
+		.step = 1,
+	},
+	[3] = {
+		.ops = &s5c73m3_ctrl_ops,
+		.id = V4L2_CID_FLASH_MODE,
+		.type = V4L2_CTRL_TYPE_MENU,
+		.name = "Flash Mode",
+		.max = ARRAY_SIZE(s5c73m3_flash_mode_menu) - 1,
+		.qmenu = s5c73m3_flash_mode_menu,
+	},
+};
+
+/* Supported manual ISO values */
+static const s64 iso_qmenu[] = {
+	/* REG_ISO: 0x0001...0x0004 */
+	100, 200, 400, 800,
+};
+
+/* Supported exposure bias values (-2.0EV...+2.0EV) */
+static const s64 ev_bias_qmenu[] = {
+	/* REG_EV: 0x0000...0x0008 */
+	-2000, -1500, -1000, -500, 0, 500, 1000, 1500, 2000
+};
+
+int s5c73m3_init_controls(struct s5c73m3 *state)
+{
+	const struct v4l2_ctrl_ops *ops = &s5c73m3_ctrl_ops;
+	struct s5c73m3_ctrls *ctrls = &state->ctrls;
+	struct v4l2_ctrl_handler *hdl = &ctrls->handler;
+
+	int err = v4l2_ctrl_handler_init(hdl, 26);
+	if (err)
+		return err;
+
+	/* White balance */
+	ctrls->auto_wb = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
+
+	ctrls->wb_preset = v4l2_ctrl_new_std_menu(hdl, ops,
+			V4L2_CID_WHITE_BALANCE_PRESET,
+			7, ~0xfe, V4L2_WHITE_BALANCE_PRESET_DAYLIGHT);
+
+	/* Exposure (only automatic exposure) */
+	ctrls->auto_exposure = v4l2_ctrl_new_std_menu(hdl, ops,
+			V4L2_CID_EXPOSURE_AUTO, 0, ~0x01, V4L2_EXPOSURE_AUTO);
+
+	ctrls->exposure_bias = v4l2_ctrl_new_std_int_menu(hdl, ops,
+			V4L2_CID_AUTO_EXPOSURE_BIAS,
+			ARRAY_SIZE(ev_bias_qmenu) - 1,
+			ARRAY_SIZE(ev_bias_qmenu)/2 - 1,
+			ev_bias_qmenu);
+
+	ctrls->exposure_metering = v4l2_ctrl_new_std_menu(hdl, ops,
+			V4L2_CID_EXPOSURE_METERING,
+			2, ~0x7, V4L2_EXPOSURE_METERING_AVERAGE);
+
+	/* Auto focus */
+	ctrls->focus_auto = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_FOCUS_AUTO, 0, 1, 1, 0);
+
+	ctrls->af_start = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_AUTO_FOCUS_START, 0, 1, 1, 0);
+
+	ctrls->af_stop = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_AUTO_FOCUS_STOP, 0, 1, 1, 0);
+
+	ctrls->af_status = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_AUTO_FOCUS_STATUS, 0, 0x07, 0, 0);
+
+	/* whole frame and spot */
+	ctrls->af_distance = v4l2_ctrl_new_std_menu(hdl, ops,
+			V4L2_CID_AUTO_FOCUS_DISTANCE, 2, 0,
+			V4L2_AUTO_FOCUS_DISTANCE_NORMAL);
+
+	ctrls->af_area = v4l2_ctrl_new_std_menu(hdl, ops,
+			V4L2_CID_AUTO_FOCUS_AREA, 1, ~0x03,
+			V4L2_AUTO_FOCUS_AREA_ALL);
+
+	/* ISO sensitivity */
+	ctrls->auto_iso = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_ISO_SENSITIVITY_AUTO, 0, 1, 1, 1);
+
+	ctrls->iso = v4l2_ctrl_new_std_int_menu(hdl, ops,
+			V4L2_CID_ISO_SENSITIVITY, ARRAY_SIZE(iso_qmenu) - 1,
+			ARRAY_SIZE(iso_qmenu)/2 - 1, iso_qmenu);
+
+	ctrls->contrast = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_CONTRAST, -2, 2, 1, 0);
+
+	ctrls->saturation = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_SATURATION, -2, 2, 1, 0);
+
+	ctrls->sharpness = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_SHARPNESS, -2, 2, 1, 0);
+
+	ctrls->zoom = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_ZOOM_ABSOLUTE, 0, 30, 1, 0);
+
+	ctrls->colorfx = v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
+			V4L2_COLORFX_AQUA, ~0x40f, V4L2_COLORFX_NONE);
+
+
+	ctrls->wdr = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_WIDE_DYNAMIC_RANGE, 0, 1, 1, 0);
+
+	ctrls->stabilization = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_IMAGE_STABILIZATION, 0, 1, 1, 0);
+
+	/* ctrls->ppwr_line_freq = v4l2_ctrl_new_std_menu(hdl, ops, */
+	/*		V4L2_CID_POWER_LINE_FREQUENCY, */
+	/*		V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0, */
+	/*		V4L2_CID_POWER_LINE_FREQUENCY_AUTO); */
+
+	ctrls->jpeg_quality = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_JPEG_COMPRESSION_QUALITY, 1, 100, 1, 80);
+
+	ctrls->scene_mode = v4l2_ctrl_new_std_menu(hdl, ops,
+			V4L2_CID_SCENE_MODE, V4L2_SCENE_MODE_TEXT, ~0x3fff,
+			V4L2_SCENE_MODE_NONE);
+
+	ctrls->ae_awb_lock = v4l2_ctrl_new_std(hdl, ops,
+			V4L2_CID_3A_LOCK, 0, 0x7, 0, 0);
+
+	v4l2_ctrl_new_custom(hdl, &s5c73m3_ctrls[0], NULL);
+	ctrls->capture_ctx = v4l2_ctrl_new_custom(hdl, &s5c73m3_ctrls[1], NULL);
+	ctrls->snapshot = v4l2_ctrl_new_custom(hdl, &s5c73m3_ctrls[2], NULL);
+	ctrls->flash_mode = v4l2_ctrl_new_custom(hdl, &s5c73m3_ctrls[3], NULL);
+
+	if (hdl->error) {
+		err = hdl->error;
+		v4l2_ctrl_handler_free(hdl);
+		return err;
+	}
+
+	v4l2_ctrl_auto_cluster(3, &ctrls->auto_exposure, 0, false);
+	ctrls->auto_iso->flags |= V4L2_CTRL_FLAG_VOLATILE |
+				V4L2_CTRL_FLAG_UPDATE;
+	v4l2_ctrl_auto_cluster(2, &ctrls->auto_iso, 0, false);
+	v4l2_ctrl_auto_cluster(2, &ctrls->auto_wb, 0, false);
+	ctrls->af_status->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	v4l2_ctrl_cluster(6, &ctrls->focus_auto);
+
+	state->subdev.ctrl_handler = hdl;
+
+	return 0;
+}
diff --git a/drivers/media/video/s5c73m3/s5c73m3-spi.c b/drivers/media/video/s5c73m3/s5c73m3-spi.c
new file mode 100644
index 0000000..50c915e
--- /dev/null
+++ b/drivers/media/video/s5c73m3/s5c73m3-spi.c
@@ -0,0 +1,126 @@
+/*
+ * Samsung LSI S5C73M3 8M pixel camera driver
+ *
+ * Copyright (C) 2012, Samsung Electronics, Co., Ltd.
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/sizes.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/media.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+
+#include "s5c73m3.h"
+
+#define S5C73M3_SPI_DRV_NAME "S5C73M3-SPI"
+
+/*
+ * SPI driver
+ */
+static int spi_xmit(struct spi_device *spi_dev, const void *addr, const int len)
+{
+	struct spi_message msg;
+	int r;
+	struct spi_transfer xfer = {
+		.tx_buf	= addr,
+		.len	= len,
+	};
+
+	if (spi_dev == NULL) {
+		dev_err(&spi_dev->dev, "SPI device is uninitialized\n");
+		return -ENODEV;
+	}
+
+	spi_message_init(&msg);
+	spi_message_add_tail(&xfer, &msg);
+
+	r = spi_sync(spi_dev, &msg);
+	if (r < 0)
+		dev_err(&spi_dev->dev, "%s spi_sync failed %d\n", __func__, r);
+
+	return r;
+}
+
+int s5c73m3_spi_write(struct s5c73m3 *state, const void *addr,
+		      const unsigned int len, const unsigned int tx_size)
+{
+	struct spi_device *spi_dev = state->spi_dev;
+	u32 count = len / tx_size;
+	u32 extra = len % tx_size;
+	unsigned int i, j = 0;
+	u8 padding[32];
+	int r = 0;
+
+	memset(padding, 0, sizeof(padding));
+
+	for (i = 0; i < count ; i++) {
+		r = spi_xmit(spi_dev, addr + j, tx_size);
+		if (r < 0)
+			return r;
+		j += tx_size;
+	}
+
+	if (extra > 0) {
+		r = spi_xmit(spi_dev, addr + j, extra);
+		if (r < 0)
+			return r;
+	}
+
+	return spi_xmit(spi_dev, padding, sizeof(padding));
+}
+
+static int __devinit s5c73m3_spi_probe(struct spi_device *spi)
+{
+	int r;
+	struct s5c73m3 *state = container_of(spi->dev.driver, struct s5c73m3,
+					     spidrv.driver);
+	spi->bits_per_word = 32;
+
+	r = spi_setup(spi);
+	if (r < 0) {
+		dev_err(&spi->dev, "spi_setup() failed\n");
+		return r;
+	}
+
+	mutex_lock(&state->lock);
+	state->spi_dev = spi;
+	mutex_unlock(&state->lock);
+
+	v4l2_info(&state->subdev, "S5C73M3 SPI probed successfully\n");
+	return 0;
+}
+
+static int __devexit s5c73m3_spi_remove(struct spi_device *spi)
+{
+	return 0;
+}
+
+int s5c73m3_register_spi_driver(struct s5c73m3 *state)
+{
+	struct spi_driver *spidrv = &state->spidrv;
+
+	spidrv->remove = __devexit_p(s5c73m3_spi_remove);
+	spidrv->probe = s5c73m3_spi_probe;
+	spidrv->driver.name = S5C73M3_SPI_DRV_NAME;
+	spidrv->driver.bus = &spi_bus_type;
+	spidrv->driver.owner = THIS_MODULE;
+
+	return spi_register_driver(spidrv);
+}
+
+void s5c73m3_unregister_spi_driver(struct s5c73m3 *state)
+{
+	spi_unregister_driver(&state->spidrv);
+}
diff --git a/drivers/media/video/s5c73m3/s5c73m3.c b/drivers/media/video/s5c73m3/s5c73m3.c
new file mode 100644
index 0000000..2ee78bb
--- /dev/null
+++ b/drivers/media/video/s5c73m3/s5c73m3.c
@@ -0,0 +1,1235 @@
+/*
+ * Samsung LSI S5C73M3 8M pixel camera driver
+ *
+ * Copyright (C) 2012, Samsung Electronics, Co., Ltd.
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#define pr_fmt(fmt) "%s:%d " fmt, __func__, __LINE__
+
+#include <asm/sizes.h>
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/media.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/videodev2.h>
+#include <media/media-entity.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-mediabus.h>
+#include <media/s5c73m3.h>
+
+#include "s5c73m3.h"
+
+int s5c73m3_dbg = 3;
+module_param_named(debug, s5c73m3_dbg, int, 0644);
+
+static int inc_fw_index;
+module_param(inc_fw_index, int, 0644);
+
+static const char * const s5c73m3_supply_names[S5C73M3_MAX_SUPPLIES] = {
+	"VDD_INT",	/* Digital Core supply (1.2V), CAM_ISP_CORE_1.2V */
+	"VDDA",		/* Analog Core supply (1.2V), CAM_SENSOR_CORE_1.2V */
+	"VDD_REG",	/* Regulator input supply (2.8V), CAM_SENSOR_A2.8V */
+	"VDDIO_HOST",	/* Digital Host I/O power supply (1.8V...2.8V),
+			   CAM_ISP_SENSOR_1.8V */
+	"VDDIO_CIS",	/* Digital CIS I/O power (1.2V...1.8V),
+			   CAM_ISP_MIPI_1.2V */
+	"VDD_AF",	/* Lens, CAM_AF_2.8V */
+};
+
+static const char *firmware_files[] = {
+	"SlimISP.bin",
+	"SlimISP_OA.bin",
+/*	"SlimISP_OB.bin",
+	"SlimISP_OD.bin",
+	"SlimISP_SC.bin",
+	"SlimISP_SD.bin",
+	"SlimISP_GC.bin",
+	"SlimISP_GD.bin",
+	"SlimISP_GE.bin",
+	"SlimISP_GF.bin",
+	"SlimISP_ZC.bin",
+	"SlimISP_ZD.bin",
+	"SlimISP_ZE.bin",
+	"SlimISP_ZF.bin",
+*/
+};
+
+static const struct s5c73m3_frame_size s5c73m3_video_resolutions[] = {
+	{ 320,	240,	0x01, 0 },
+	{ 400,	300,	0x02, 0 },
+	{ 640,	480,	0x03, 0 },
+	{ 800,	600,	0x04, 0 },
+	{ 960,	720,	0x05, 0 },
+	{ 1280,	720,	0x06, 1 },
+	{ 1280,	960,	0x07, 1 },
+	{ 1600,	1200,	0x08, 1 },
+	{ 1632,	1224,	0x09, 1 },
+	{ 1920,	1080,	0x0a, 1 },
+	{ 1920,	1440,	0x0b, 1 },
+	{ 2304,	1296,	0x0c, 1 },
+	{ 2304,	1728,	0x0d, 1 },
+};
+
+static const struct s5c73m3_frame_size s5c73m3_snapshot_resolutions[] = {
+	{ 640,	480,	0x10, 0 },
+	{ 1280,	720,	0x40, 0 },
+	{ 1600,	1200,	0x70, 1 },
+	{ 2048,	1152,	0x80, 0 },
+	{ 2048,	1536,	0x90, 0 },
+	{ 3264,	2304,	0xe0, 0 },
+	{ 3264,	2448,	0xf0, 0 },
+};
+
+struct s5c73m3_regval {
+	u16 addr;
+	u16 val;
+};
+
+static const struct s5c73m3_pixfmt s5c73m3_formats[] = {
+	{
+		.code		= V4L2_MBUS_FMT_VYUY8_2X8,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+	}, {
+		.code		= V4L2_MBUS_FMT_JPEG_1X8,
+		.colorspace	= V4L2_COLORSPACE_JPEG,
+		.mipi_data_type	= 1,
+	},
+};
+
+static const struct s5c73m3_interval s5c73m3_intervals[] = {
+	/* TODO: update pixel resolutions corresponding to the frame rates */
+	{ REG_AE_MODE_FIXED_7FPS, {142857, 1000000}, {1280, 1024} }, /* 7 fps */
+	{ REG_AE_MODE_FIXED_15FPS, {66667, 1000000}, {1280, 1024} }, /* 15 fps */
+	{ REG_AE_MODE_FIXED_20FPS, {50000, 1000000}, {1280, 720} },  /* 20 fps */
+	{ REG_AE_MODE_FIXED_30FPS, {33333, 1000000}, {640, 480} },   /* 30 fps */
+	{ REG_AE_MODE_FIXED_120FPS, {8333, 1000000}, {640, 480} },   /* 120 fps */
+};
+
+#define S5C73M3_DEFAULT_FRAME_INTERVAL 3 /* 30 fps */
+
+static inline bool is_user_defined_dt(enum v4l2_mbus_pixelcode code)
+{
+	return code == V4L2_MBUS_FMT_JPEG_1X8;
+}
+
+static void s5c73m3_fill_mbus_fmt(struct v4l2_mbus_framefmt *mf,
+				  const struct s5c73m3_frame_size *fs,
+				  u32 code)
+{
+	mf->width = fs->width;
+	mf->height = fs->height;
+	mf->code = code;
+	mf->colorspace = V4L2_COLORSPACE_JPEG;
+	mf->field = V4L2_FIELD_NONE;
+}
+
+int s5c73m3_i2c_write(struct i2c_client *client, u16 addr, u16 data)
+{
+	u8 buf[4] = { addr >> 8, addr & 0xff, data >> 8, data & 0xff };
+
+	int ret = i2c_master_send(client, buf, sizeof(buf));
+
+	v4l_dbg(4, s5c73m3_dbg, client, "%s: addr 0x%04x, data 0x%04x\n",
+		 __func__, addr, data);
+
+	if (ret == 4)
+		return 0;
+
+	return ret < 0 ? ret : -EREMOTEIO;
+}
+
+static int s5c73m3_i2c_bulk_write(struct i2c_client *client, const u32 *regs)
+{
+	int i, ret = 0;
+
+	for (i = 0; regs[i] != S5C73M3_ARRAY_END && !ret; i++)
+		ret = s5c73m3_i2c_write(client, regs[i] >> 16, regs[i]);
+
+	return ret;
+}
+
+static int s5c73m3_i2c_read(struct i2c_client *client, u16 addr, u16 *data)
+{
+	int ret;
+	u8 rbuf[2], wbuf[2] = { addr >> 8, addr & 0xff };
+	struct i2c_msg msg[2] = {
+		{
+			.addr = client->addr,
+			.flags = 0,
+			.len = sizeof(wbuf),
+			.buf = wbuf
+		}, {
+			.addr = client->addr,
+			.flags = I2C_M_RD,
+			.len = sizeof(rbuf),
+			.buf = rbuf
+		}
+	};
+	/*
+	 * Issue repeated START after writing 2 address bytes and
+	 * just one STOP only after reading the data bytes.
+	 */
+	ret = i2c_transfer(client->adapter, msg, 2);
+	if (ret == 2) {
+		*data = be16_to_cpup((u16 *)rbuf);
+		v4l2_dbg(4, s5c73m3_dbg, client,
+			 "%s: addr: 0x%04x, data: 0x%04x\n",
+			 __func__, addr, *data);
+		return 0;
+	}
+
+	v4l2_err(client, "I2C read failed: addr: %04x, (%d)\n", addr, ret);
+
+	return ret >= 0 ? -EREMOTEIO : ret;
+}
+
+static int s5c73m3_write(struct i2c_client *client, u32 addr, u16 data)
+{
+	int ret;
+
+	ret = s5c73m3_i2c_write(client, REG_CMDWR_ADDRH, addr >> 16);
+	if (ret < 0)
+		return ret;
+
+	ret = s5c73m3_i2c_write(client, REG_CMDWR_ADDRL, addr & 0xffff);
+	if (ret < 0)
+		return ret;
+
+	return s5c73m3_i2c_write(client, REG_CMDBUF_ADDR, data);
+}
+
+int s5c73m3_read(struct i2c_client *client, u32 addr, u16 *data)
+{
+	int ret;
+
+	ret = s5c73m3_i2c_write(client, AHB_MSB_ADDR_PTR, 0x3310);
+	if (ret < 0)
+		return ret;
+
+	ret = s5c73m3_i2c_write(client, REG_CMDRD_ADDRH, addr >> 16);
+	if (ret < 0)
+		return ret;
+
+	ret = s5c73m3_i2c_write(client, REG_CMDRD_ADDRL, addr & 0xffff);
+	if (ret < 0)
+		return ret;
+
+	return s5c73m3_i2c_read(client, REG_CMDBUF_ADDR, data);
+}
+
+static int s5c73m3_check_status(struct s5c73m3 *state, unsigned int value)
+{
+	unsigned long end = jiffies + msecs_to_jiffies(500);
+	int ret = 0;
+	u16 status;
+
+	while (time_is_after_jiffies(end)) {
+		ret = s5c73m3_read(state->i2c_client, 0x00095080, &status);
+		if (ret < 0)
+			return ret;
+		if (status == value)
+			return 0;
+		usleep_range(5000, 10000);
+
+		v4l2_dbg(1, s5c73m3_dbg, &state->subdev, "status: %#x\n",
+			 status);
+	}
+
+	return ret < 0 ? ret : -ETIMEDOUT;
+}
+
+int s5c73m3_write_cmd(struct s5c73m3 *state, u32 addr, u16 data)
+{
+	struct i2c_client *client = state->i2c_client;
+	int r;
+
+	r = s5c73m3_check_status(state, 0xffff);
+	if (r < 0)
+		return r;
+
+	r = s5c73m3_i2c_write(client, AHB_MSB_ADDR_PTR, 0x3310);
+	if (r < 0)
+		return r;
+
+	r = s5c73m3_i2c_write(client, REG_CMDWR_ADDRH, 0x0009);
+	if (r < 0)
+		return r;
+
+	r = s5c73m3_i2c_write(client, REG_CMDWR_ADDRL, 0x5000);
+	if (r < 0)
+		return r;
+
+	r = s5c73m3_i2c_write(client, REG_CMDBUF_ADDR, addr & 0xffff);
+	if (r < 0)
+		return r;
+
+	r = s5c73m3_i2c_write(client, REG_CMDBUF_ADDR, data);
+	if (r < 0)
+		return r;
+
+	r = s5c73m3_i2c_write(client, REG_CMDWR_ADDRL, 0x5080);
+	if (r < 0)
+		return r;
+
+	return s5c73m3_i2c_write(client, REG_CMDBUF_ADDR, 0x0001);
+}
+
+static int s5c73m3_set_af_softlanding(struct v4l2_subdev *sd)
+{
+	return 0;
+}
+
+static int s5c73m3_load_fw(struct v4l2_subdev *sd)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	const struct firmware *fw;
+	int r;
+
+	r = request_firmware(&fw, firmware_files[state->fw_index],
+			     &client->dev);
+	if (r < 0) {
+		v4l2_err(sd, "Firmware request failed (%s)\n",
+			 firmware_files[state->fw_index]);
+		return -EINVAL;
+	}
+	/* TODO: Sanity check on firmware size */
+
+	printk(KERN_CONT "Loading firmware (%s, %d B)...",
+	       firmware_files[state->fw_index], fw->size);
+
+	/* FIXME: Passing tx_size more than 64 leads to an oops */
+	r = s5c73m3_spi_write(state, fw->data, fw->size, 64 /*60 * SZ_1K*/);
+	if (r < 0)
+		v4l2_err(sd, "SPI write failed\n");
+	else
+		printk(KERN_CONT "done.\n");
+
+	release_firmware(fw);
+
+	if (inc_fw_index) {
+		if (++state->fw_index >= ARRAY_SIZE(firmware_files))
+			state->fw_index = 0;
+	}
+
+	return r;
+}
+
+/*
+ * v4l2_subdev video operations
+ */
+
+static int s5c73m3_set_frame_size(struct s5c73m3 *state)
+{
+	const struct s5c73m3_frame_size *prev_size = state->prev_pix_size;
+	unsigned int chg_mode;
+	int r = 0;
+
+	v4l2_dbg(1, s5c73m3_dbg, &state->subdev,
+		 "Preview size: %dx%d, reg_val: 0x%x\n",
+		 prev_size->width, prev_size->height, prev_size->reg_val);
+
+	/* FIXME: */
+	if (state->format[PREVIEW_IDX].code == V4L2_MBUS_FMT_JPEG_1X8)
+		chg_mode = CHG_MODE_INTERLEAVED;
+	else
+		chg_mode = CHG_MODE_YUV;
+
+	chg_mode |= prev_size->reg_val;
+
+	r = s5c73m3_write_cmd(state, REG_CHG_MODE, chg_mode);
+	if (r < 0)
+		return r;
+
+	/* s5c73m3_set_zoom(sd, 0); */
+	return r;
+}
+
+static int s5c73m3_set_frame_rate(struct s5c73m3 *state)
+{
+	int ret;
+
+	/*
+	 *  Image stabilization and frame rate are configured in same register.
+	 *  TODO: handle REG_AE_MODE_AUTO_SET
+	 */
+	if (state->ctrls.stabilization->val)
+		return 0;
+
+	if (WARN_ON(state->fiv == NULL))
+		return -EINVAL;
+
+	ret = s5c73m3_write_cmd(state, REG_AE_MODE, state->fiv->fps_reg);
+	if (!ret)
+		state->apply_fiv = 0;
+
+	return ret;
+}
+
+static int __s5c73m3_s_stream(struct s5c73m3 *state,
+			      struct v4l2_subdev *sd, int on)
+{
+	u16 mode;
+	int ret;
+
+	if (state->apply_fmt) {
+		/* FIXME: */
+		if (state->format[PREVIEW_IDX].code == V4L2_MBUS_FMT_JPEG_1X8)
+			mode = REG_IMG_OUTPUT_INTERLEAVED;
+		else
+			mode = REG_IMG_OUTPUT_YUV;
+
+		ret = s5c73m3_write_cmd(state, REG_IMG_OUTPUT, mode);
+		if (!ret)
+			ret = s5c73m3_set_frame_size(state);
+		if (ret)
+			return ret;
+		state->apply_fmt = 0;
+	}
+
+	switch (state->ctrls.capture_ctx->val) {
+	case V4L2_CAPTURE_CTX_PREVIEW:
+		v4l2_info(sd, "preview %s", on ? "on" : "off");
+		/* TODO: */
+		break;
+	case V4L2_CAPTURE_CTX_STILL:
+		v4l2_info(sd, "still capture %s", on ? "on" : "off");
+		/* TODO: */
+		break;
+	case V4L2_CAPTURE_CTX_CAMCORDER:
+		/* TODO: */
+		break;
+	}
+
+	ret = s5c73m3_write_cmd(state, REG_SENSOR_STREAMING, !!on);
+	if (ret || !on)
+		return ret;
+
+	ret = s5c73m3_check_status(state, 0xffff);
+	if (ret)
+		return ret;
+	/* if (state->apply_fiv) */
+		/* ret = s5c73m3_set_frame_rate(state); */
+
+	return ret;
+}
+
+static int s5c73m3_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	int ret;
+
+	mutex_lock(&state->lock);
+	ret = __s5c73m3_s_stream(state, sd, on);
+	mutex_unlock(&state->lock);
+
+	return ret;
+}
+
+static int s5c73m3_system_status_wait(struct s5c73m3 *state, u32 value,
+				      unsigned int delay, unsigned int steps)
+{
+	u16 reg = 0;
+
+	while (steps-- > 0) {
+		int ret = s5c73m3_read(state->i2c_client, 0x30100010, &reg);
+		if (ret < 0)
+			return ret;
+		if (reg == value)
+			return 0;
+		usleep_range(delay, delay + 25);
+	}
+	return -ETIMEDOUT;
+}
+
+static int s5c73m3_spi_boot(struct s5c73m3 *state, bool load_fw)
+{
+	struct i2c_client *client = state->i2c_client;
+	struct v4l2_subdev *sd = &state->subdev;
+	u16 sensor_fw;
+	int i, r;
+
+	/* Run ARM MCU */
+	r = s5c73m3_write(client, 0x30000004, 0xffff);
+	if (r < 0)
+		return r;
+
+	usleep_range(400, 500);
+
+	/* Check booting status */
+	r = s5c73m3_system_status_wait(state, 0x0c, 4, 150);
+	if (r < 0) {
+		v4l2_err(sd, "Booting failed: %d\n", r);
+		return r;
+	}
+
+	/* P,M,S and Boot Mode */
+	r = s5c73m3_write(client, 0x30100014, 0x2146);
+	if (r < 0)
+		return r;
+
+	r = s5c73m3_write(client, 0x30100010, 0x210c);
+	if (r < 0)
+		return r;
+
+	usleep_range(200, 250);
+
+	/* Check SPI status */
+	r = s5c73m3_system_status_wait(state, 0x210d, 60, 5000);
+	if (r < 0) {
+		v4l2_err(sd, "SPI not ready: %d\n", r);
+		return r;
+	}
+
+	/* Firmware download over SPI */
+	if (load_fw)
+		s5c73m3_load_fw(sd);
+
+	/* MCU reset */
+	r = s5c73m3_write(client, 0x30000004, 0xfffd);
+	if (r < 0)
+		return r;
+
+	/* Remap */
+	r = s5c73m3_write(client, 0x301000a4, 0x0183);
+	if (r < 0)
+		return r;
+
+	/* MCU restart */
+	r = s5c73m3_write(client, 0x30000004, 0xffff);
+
+	if (r < 0 || !load_fw)
+		return r;
+
+	for (i = 0; i < 3; i++) {
+		r = s5c73m3_read(client, 0x00000060 + i * 2, &sensor_fw);
+		if (r < 0)
+			return r;
+		state->sensor_fw[i * 2] = sensor_fw & 0xff;
+		state->sensor_fw[i * 2 + 1] = (sensor_fw >> 8) & 0xff;
+	}
+	state->sensor_fw[i * 2 + 2] = '\0';
+
+	v4l2_info(sd, "Sensor version: %s\n", state->sensor_fw);
+	return r;
+}
+
+static int s5c73m3_isp_init(struct s5c73m3 *state)
+{
+	struct i2c_client *client = state->i2c_client;
+	int ret;
+	static const u32 init_regs[] = {
+		0x00500009,
+		0x00545000,
+		0x0f140B08,
+		0x0f140000,
+		0x0f140900,
+		0x0f140403, /*640MHz*/
+		0x00545080,
+		0x0f140002,
+		S5C73M3_ARRAY_END
+	};
+
+	ret = s5c73m3_spi_boot(state, true);
+	if (ret < 0)
+		return ret;
+
+	return s5c73m3_i2c_bulk_write(client, init_regs);
+}
+
+static const struct s5c73m3_pixfmt *s5c73m3_get_pixfmt(
+				struct v4l2_mbus_framefmt *mf)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(s5c73m3_formats); i++) {
+		if (mf->colorspace == s5c73m3_formats[i].colorspace &&
+		    mf->code == s5c73m3_formats[i].code)
+			return &s5c73m3_formats[i];
+	}
+
+	return &s5c73m3_formats[0];
+}
+
+static int s5c73m3_try_format(struct s5c73m3 *state,
+			      struct v4l2_mbus_framefmt *mf,
+			      const struct s5c73m3_frame_size **fs,
+			      int op_mode)
+{
+	unsigned int i, min_err = UINT_MAX;
+	const struct s5c73m3_frame_size
+		*fsize = state->pix_sizes[op_mode],
+		*match = NULL;
+	const struct s5c73m3_pixfmt *pixfmt;
+
+	for (i = 0; i < state->pix_sizes_len[op_mode]; i++) {
+		int err;
+		err = abs(fsize->width - mf->width)
+			  + abs(fsize->height - mf->height);
+
+		if (err < min_err) {
+			min_err = err;
+			match = fsize;
+		}
+		fsize++;
+	}
+
+	if (match == NULL)
+		return -EINVAL;
+	if (fs)
+		*fs = match;
+
+	pixfmt = s5c73m3_get_pixfmt(mf);
+
+	s5c73m3_fill_mbus_fmt(mf, match, pixfmt->code);
+
+	v4l2_dbg(1, s5c73m3_dbg, &state->subdev, "%dx%d, code: %#x\n",
+		 match->width, match->height, pixfmt->code);
+
+	return 0;
+}
+
+/*
+ * V4L2 subdev pad level and video operations
+ */
+
+static int s5c73m3_g_frame_interval(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_frame_interval *fi)
+{
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+
+	mutex_lock(&state->lock);
+	fi->interval = state->fiv->interval;
+	mutex_unlock(&state->lock);
+
+	return 0;
+}
+
+static int __s5c73m3_set_frame_interval(struct s5c73m3 *state,
+					struct v4l2_subdev_frame_interval *fi)
+{
+	const struct s5c73m3_frame_size *prev_size = state->prev_pix_size;
+	const struct s5c73m3_interval *fiv = &s5c73m3_intervals[0];
+	unsigned int err, min_err = UINT_MAX;
+	unsigned int i, fr_time;
+
+	if (fi->interval.denominator == 0)
+		return -EINVAL;
+
+	/* Frame interval in ms */
+	fr_time = fi->interval.numerator * 1000 / fi->interval.denominator;
+
+	for (i = 0; i < ARRAY_SIZE(s5c73m3_intervals); i++) {
+		const struct s5c73m3_interval *iv = &s5c73m3_intervals[i];
+
+		if (prev_size->width > iv->size.width ||
+		    prev_size->height > iv->size.height)
+			continue;
+
+		err = abs(iv->interval.numerator / 10000 - fr_time);
+		if (err < min_err) {
+			fiv = iv;
+			min_err = err;
+		}
+	}
+	state->fiv = fiv;
+
+	v4l2_dbg(1, s5c73m3_dbg, &state->subdev,
+		 "Changed frame interval to %u us\n", fiv->interval.numerator);
+	return 0;
+}
+
+static int s5c73m3_s_frame_interval(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_frame_interval *fi)
+{
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	int ret;
+
+	v4l2_dbg(1, s5c73m3_dbg, sd, "Setting %d/%d frame interval\n",
+		 fi->interval.numerator, fi->interval.denominator);
+
+	mutex_lock(&state->lock);
+
+	ret = __s5c73m3_set_frame_interval(state, fi);
+	if (!ret) {
+		if (state->streaming)
+			ret = s5c73m3_set_frame_rate(state);
+		else
+			state->apply_fiv = 1;
+	}
+	mutex_unlock(&state->lock);
+	return ret;
+}
+
+static int s5c73m3_enum_frame_interval(struct v4l2_subdev *sd,
+			      struct v4l2_subdev_fh *fh,
+			      struct v4l2_subdev_frame_interval_enum *fie)
+{
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	const struct s5c73m3_interval *fi;
+	int ret = 0;
+
+	if (fie->index > ARRAY_SIZE(s5c73m3_intervals))
+		return -EINVAL;
+
+	v4l_bound_align_image(&fie->width, S5C73M3_WIN_WIDTH_MIN,
+			      S5C73M3_WIN_WIDTH_MAX, 1,
+			      &fie->height, S5C73M3_WIN_HEIGHT_MIN,
+			      S5C73M3_WIN_HEIGHT_MAX, 1, 0);
+
+	mutex_lock(&state->lock);
+	fi = &s5c73m3_intervals[fie->index];
+	if (fie->width > fi->size.width || fie->height > fi->size.height)
+		ret = -EINVAL;
+	else
+		fie->interval = fi->interval;
+	mutex_unlock(&state->lock);
+
+	return ret;
+}
+
+static int s5c73m3_get_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_fh *fh,
+			   struct v4l2_subdev_format *fmt)
+{
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	struct v4l2_mbus_framefmt *mf;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+		mf = v4l2_subdev_get_try_format(fh, 0);
+		fmt->format = *mf;
+		return 0;
+	}
+	mutex_lock(&state->lock);
+
+	if (fmt->pad == S5C73M3_OUTIF_SOURCE_PAD)
+		fmt->format = state->format[PREVIEW_IDX];
+	else
+		fmt->format = state->format[CAPTURE_IDX];
+
+	mutex_unlock(&state->lock);
+	return 0;
+}
+
+static int s5c73m3_set_fmt(struct v4l2_subdev *sd,
+			   struct v4l2_subdev_fh *fh,
+			   struct v4l2_subdev_format *fmt)
+{
+	const struct s5c73m3_frame_size *frame_size = NULL;
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	struct v4l2_mbus_framefmt *mf;
+	int idx, ret = 0;
+
+	mutex_lock(&state->lock);
+
+	if (fmt->pad == S5C73M3_OUTIF_SOURCE_PAD)
+		idx = PREVIEW_IDX;
+	else
+		idx = CAPTURE_IDX;
+	s5c73m3_try_format(state, &fmt->format, &frame_size, idx);
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
+		mf = v4l2_subdev_get_try_format(fh, fmt->pad);
+	} else {
+		if (state->streaming && idx != PREVIEW_IDX) {
+			ret = -EBUSY;
+		} else {
+			mf = &state->format[idx];
+			/* if (!state->power) */
+				state->apply_fmt = 1;
+		}
+	}
+	if (!ret && mf) {
+		*mf = fmt->format;
+		if (frame_size) {
+			state->prev_pix_size = frame_size;
+			/* if (state->power) */
+			/*	ret = s5c73m3_set_frame_size(state); */
+		}
+
+		v4l2_dbg(1, s5c73m3_dbg, sd, "%s: %dx%d, code: 0x%x\n",
+			 __func__, mf->width, mf->height, mf->code);
+	}
+
+	pr_info("reg_val: 0x%x\n", state->prev_pix_size->reg_val);
+
+	mutex_unlock(&state->lock);
+
+	return ret;
+}
+
+static int s5c73m3_enum_mbus_code(struct v4l2_subdev *sd,
+				  struct v4l2_subdev_fh *fh,
+				  struct v4l2_subdev_mbus_code_enum *code)
+{
+	if (code->index >= ARRAY_SIZE(s5c73m3_formats))
+		return -EINVAL;
+
+	code->code = s5c73m3_formats[code->index].code;
+	return 0;
+}
+
+static int s5c73m3_enum_frame_size(struct v4l2_subdev *sd,
+				   struct v4l2_subdev_fh *fh,
+				   struct v4l2_subdev_frame_size_enum *fse)
+{
+	int i = ARRAY_SIZE(s5c73m3_formats);
+
+	if (fse->index > 0)
+		return -EINVAL;
+
+	while (--i)
+		if (fse->code == s5c73m3_formats[i].code)
+			break;
+
+	fse->code = s5c73m3_formats[i].code;
+	fse->min_width  = S5C73M3_WIN_WIDTH_MIN;
+	fse->max_width  = S5C73M3_WIN_WIDTH_MAX;
+	fse->max_height = S5C73M3_WIN_HEIGHT_MIN;
+	fse->min_height = S5C73M3_WIN_HEIGHT_MAX;
+
+	return 0;
+}
+
+static int s5c73m3_set_selection(struct v4l2_subdev *sd,
+				struct v4l2_subdev_fh *fh,
+				struct v4l2_subdev_selection *sel)
+{
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	struct v4l2_mbus_framefmt *mf = &state->format[PREVIEW_IDX];
+	struct v4l2_rect *r = &sel->r;
+
+	v4l2_dbg(1, s5c73m3_dbg, sd, "%s: (%d,%d) %dx%d, %#x\n", __func__,
+		 r->left, r->top, r->width, r->height, sel->target);
+
+	if (sel->target != V4L2_SUBDEV_SEL_TGT_AUTO_FOCUS_ACTUAL) {
+		v4l2_err(sd, "Unsupported selection target: %#x", sel->target);
+		return -EINVAL;
+	}
+
+	r->left = clamp_t(s32, r->left, 0, mf->width);
+	r->top = clamp_t(s32, r->top, 0, mf->height);
+	r->width = 0;
+	r->height = 0;
+
+	state->focus.pos_x = r->left;
+	state->focus.pos_y = r->top;
+
+	return 0;
+}
+
+static int s5c73m3_get_selection(struct v4l2_subdev *sd,
+				 struct v4l2_subdev_fh *fh,
+				 struct v4l2_subdev_selection *sel)
+{
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	struct v4l2_mbus_framefmt *mf = &state->format[PREVIEW_IDX];
+
+	switch (sel->target) {
+	case V4L2_SUBDEV_SEL_TGT_AUTO_FOCUS_ACTUAL:
+		sel->r.left = state->focus.pos_x;
+		sel->r.top = state->focus.pos_y;
+		break;
+	case V4L2_SUBDEV_SEL_TGT_AUTO_FOCUS_BOUNDS:
+		sel->r.width = mf->width;
+		sel->r.height = mf->height;
+		sel->r.left = 0;
+		sel->r.top = 0;
+		break;
+	default:
+		v4l2_err(sd, "Unsupported selection target: %#x", sel->target);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int s5c73m3_log_status(struct v4l2_subdev *sd)
+{
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+
+	v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name);
+
+	printk(KERN_INFO "power: %d, apply_fmt: %d, apply_ctrls: %d\n",
+		state->power, state->apply_fmt, state->apply_ctrls);
+
+	return 0;
+}
+
+/*
+ * V4L2 subdev internal operations
+ */
+static int s5c73m3_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
+{
+	struct v4l2_mbus_framefmt *mf = v4l2_subdev_get_try_format(fh, 0);
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+
+	if (state->fw_error) {
+		v4l2_err(sd, "Wrong firmware state\n");
+		return -ENXIO;
+	}
+
+	s5c73m3_fill_mbus_fmt(mf, &s5c73m3_video_resolutions[0],
+			      s5c73m3_formats[0].code);
+	return 0;
+}
+
+static int s5c73m3_gpio_set_value(struct s5c73m3 *priv, int id, u32 val)
+{
+	if (!gpio_is_valid(priv->gpio[id].gpio))
+		return 0;
+	gpio_set_value(priv->gpio[id].gpio, !!val);
+	return 1;
+}
+
+static int s5c73m3_gpio_assert(struct s5c73m3 *priv, int id)
+{
+	return s5c73m3_gpio_set_value(priv, id, priv->gpio[id].level);
+}
+
+static int s5c73m3_gpio_deassert(struct s5c73m3 *priv, int id)
+{
+	return s5c73m3_gpio_set_value(priv, id, !priv->gpio[id].level);
+}
+
+static int __s5c73m3_power_on(struct s5c73m3 *state)
+{
+	int i, ret;
+
+	for (i = 0; i < S5C73M3_MAX_SUPPLIES; i++) {
+		ret = regulator_enable(state->supplies[i].consumer);
+		if (ret)
+			goto err;
+	}
+
+	s5c73m3_gpio_deassert(state, STBY);
+	usleep_range(100, 200);
+
+	s5c73m3_gpio_deassert(state, RST);
+	usleep_range(50, 100);
+
+	return 0;
+err:
+	for (--i; i >= 0; i--)
+		regulator_disable(state->supplies[i].consumer);
+	return ret;
+}
+
+static int __s5c73m3_power_off(struct s5c73m3 *state)
+{
+	int i, ret;
+
+	if (s5c73m3_gpio_assert(state, RST))
+		usleep_range(10, 50);
+
+	if (s5c73m3_gpio_assert(state, STBY))
+		usleep_range(100, 200);
+	state->streaming = 0;
+
+	for (i = S5C73M3_MAX_SUPPLIES - 1; i >= 0; i--) {
+		ret = regulator_disable(state->supplies[i].consumer);
+		if (ret)
+			goto err;
+	}
+	return 0;
+err:
+	for (++i; i < S5C73M3_MAX_SUPPLIES; i++)
+		regulator_enable(state->supplies[i].consumer);
+
+	return ret;
+}
+
+/*
+ * V4L2 subdev core and video operations
+ */
+static int s5c73m3_set_power(struct v4l2_subdev *sd, int on)
+{
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	int ret = 0;
+
+	mutex_lock(&state->lock);
+
+	if (on && !on == state->power) {
+		ret = __s5c73m3_power_on(state);
+		if (!ret)
+			ret = s5c73m3_isp_init(state);
+		if (!ret)
+			state->apply_fmt = 0;
+
+	} else if (!on && !on == state->power) {
+		ret = s5c73m3_set_af_softlanding(sd);
+		if (!ret)
+			ret = __s5c73m3_power_off(state);
+		else
+			v4l2_err(sd, "Soft landing lens failed\n");
+	}
+	if (!ret)
+		state->power += on ? 1 : -1;
+
+	v4l2_dbg(1, s5c73m3_dbg, sd, "%s: power: %d\n",
+		   __func__, state->power);
+
+	state->apply_ctrls = 1;
+	state->apply_fiv = 1;
+
+	mutex_unlock(&state->lock);
+	return ret;
+}
+
+static int s5c73m3_registered(struct v4l2_subdev *sd)
+{
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	int ret;
+
+	v4l2_dbg(1, s5c73m3_dbg, sd, "%s:\n", __func__);
+
+	mutex_lock(&state->lock);
+
+	ret = __s5c73m3_power_on(state);
+	if (ret == 0)
+		ret = s5c73m3_spi_boot(state, false);
+	__s5c73m3_power_off(state);
+
+	mutex_unlock(&state->lock);
+	return ret;
+}
+
+static const struct v4l2_subdev_internal_ops s5c73m3_internal_ops = {
+	.registered	= s5c73m3_registered,
+	.open 		= s5c73m3_open,
+};
+
+static const struct v4l2_subdev_core_ops s5c73m3_core_ops = {
+	.load_fw	= s5c73m3_load_fw,
+	.s_power	= s5c73m3_set_power,
+	.log_status	= s5c73m3_log_status,
+};
+
+static const struct v4l2_subdev_pad_ops s5c73m3_pad_ops = {
+	.enum_mbus_code		= s5c73m3_enum_mbus_code,
+	.enum_frame_size	= s5c73m3_enum_frame_size,
+	.enum_frame_interval	= s5c73m3_enum_frame_interval,
+	.set_selection 		= s5c73m3_set_selection,
+	.get_selection		= s5c73m3_get_selection,
+	.get_fmt		= s5c73m3_get_fmt,
+	.set_fmt		= s5c73m3_set_fmt,
+};
+
+static const struct v4l2_subdev_video_ops s5c73m3_video_ops = {
+	.g_frame_interval	= s5c73m3_g_frame_interval,
+	.s_frame_interval	= s5c73m3_s_frame_interval,
+	.s_stream		= s5c73m3_s_stream,
+};
+
+static const struct v4l2_subdev_ops s5c73m3_subdev_ops = {
+	.core	= &s5c73m3_core_ops,
+	.pad	= &s5c73m3_pad_ops,
+	.video	= &s5c73m3_video_ops,
+};
+
+/*
+ * GPIO control helpers
+ */
+static int s5c73m3_configure_gpio(int nr, int val, const char *name)
+{
+	unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
+	int ret;
+
+	if (!gpio_is_valid(nr))
+		return 0;
+	ret = gpio_request_one(nr, flags, name);
+	if (!ret)
+		gpio_export(nr, 0);
+	return ret;
+}
+
+static int s5c73m3_free_gpios(struct s5c73m3 *state)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(state->gpio); i++) {
+		if (!gpio_is_valid(state->gpio[i].gpio))
+			continue;
+		gpio_free(state->gpio[i].gpio);
+		state->gpio[i].gpio = -EINVAL;
+	}
+	return 0;
+}
+
+static int s5c73m3_configure_gpios(struct s5c73m3 *state,
+				   const struct s5c73m3_platform_data *pdata)
+{
+	const struct s5c73m3_gpio *gpio = &pdata->gpio_stby;
+	int ret;
+
+	state->gpio[STBY].gpio = -EINVAL;
+	state->gpio[RST].gpio  = -EINVAL;
+
+	ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_STBY");
+	if (ret) {
+		s5c73m3_free_gpios(state);
+		return ret;
+	}
+	state->gpio[STBY] = *gpio;
+	if (gpio_is_valid(gpio->gpio))
+		gpio_set_value(gpio->gpio, 0);
+
+	gpio = &pdata->gpio_reset;
+	ret = s5c73m3_configure_gpio(gpio->gpio, gpio->level, "S5C73M3_RST");
+	if (ret) {
+		s5c73m3_free_gpios(state);
+		return ret;
+	}
+	state->gpio[RST] = *gpio;
+	if (gpio_is_valid(gpio->gpio))
+		gpio_set_value(gpio->gpio, 0);
+
+	return 0;
+}
+
+static int __devinit s5c73m3_probe(struct i2c_client *client,
+				   const struct i2c_device_id *id)
+{
+	const struct s5c73m3_platform_data *pdata = client->dev.platform_data;
+	struct v4l2_subdev *sd;
+	struct s5c73m3 *state;
+	int ret, i;
+
+	if (pdata == NULL) {
+		dev_err(&client->dev, "Platform data not specified\n");
+		return -EINVAL;
+	}
+
+	state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
+	if (!state)
+		return -ENOMEM;
+
+	mutex_init(&state->lock);
+	sd = &state->subdev;
+
+	v4l2_i2c_subdev_init(sd, client, &s5c73m3_subdev_ops);
+	strlcpy(sd->name, "S5C73M3", sizeof(sd->name));
+
+	sd->internal_ops = &s5c73m3_internal_ops;
+	sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+
+	state->pads[S5C73M3_OUTIF_SOURCE_PAD].flags = MEDIA_PAD_FL_SOURCE;
+	state->pads[S5C73M3_JPEG_SINK_PAD].flags = MEDIA_PAD_FL_SINK;
+	state->pads[S5C73M3_ISP_SINK_PAD].flags = MEDIA_PAD_FL_SINK;
+	sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
+
+	ret = media_entity_init(&sd->entity, S5C73M3_NUM_PADS, state->pads, 0);
+	if (ret < 0)
+		return ret;
+
+	state->mclk_frequency = pdata->mclk_frequency;
+	state->bus_type = pdata->bus_type;
+
+	ret = s5c73m3_configure_gpios(state, pdata);
+	if (ret)
+		goto out_err1;
+
+	for (i = 0; i < S5C73M3_MAX_SUPPLIES; i++)
+		state->supplies[i].supply = s5c73m3_supply_names[i];
+
+	ret = regulator_bulk_get(&client->dev, S5C73M3_MAX_SUPPLIES,
+			       state->supplies);
+	if (ret) {
+		dev_err(&client->dev, "failed to get regulators\n");
+		goto out_err2;
+	}
+
+	ret = s5c73m3_init_controls(state);
+	if (ret)
+		goto out_err3;
+
+	state->pix_sizes[PREVIEW_IDX]	  = s5c73m3_video_resolutions;
+	state->pix_sizes_len[PREVIEW_IDX] = ARRAY_SIZE(s5c73m3_video_resolutions);
+	state->prev_pix_size		  = &s5c73m3_video_resolutions[1];
+
+	s5c73m3_fill_mbus_fmt(&state->format[PREVIEW_IDX], state->prev_pix_size,
+			      s5c73m3_formats[0].code /* FIXME */);
+
+	state->pix_sizes[CAPTURE_IDX]	  = s5c73m3_snapshot_resolutions;
+	state->pix_sizes_len[CAPTURE_IDX] = ARRAY_SIZE(s5c73m3_snapshot_resolutions);
+	state->cap_pix_size		  = &s5c73m3_snapshot_resolutions[1];
+
+	s5c73m3_fill_mbus_fmt(&state->format[CAPTURE_IDX], state->cap_pix_size,
+			      s5c73m3_formats[2].code /* FIXME */);
+
+	state->fiv = &s5c73m3_intervals[S5C73M3_DEFAULT_FRAME_INTERVAL];
+
+	ret = s5c73m3_register_spi_driver(state);
+	if (ret < 0)
+		goto out_err3;
+
+	state->i2c_client = client;
+
+	state->fw_index = 0;
+
+	v4l2_info(sd, "%s: completed succesfully\n", __func__);
+	return 0;
+
+out_err3:
+	regulator_bulk_free(S5C73M3_MAX_SUPPLIES, state->supplies);
+out_err2:
+	s5c73m3_free_gpios(state);
+out_err1:
+	media_entity_cleanup(&sd->entity);
+	return ret;
+}
+
+static int __devexit s5c73m3_remove(struct i2c_client *client)
+{
+	struct v4l2_subdev *sd = i2c_get_clientdata(client);
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+
+	v4l2_device_unregister_subdev(sd);
+
+	v4l2_ctrl_handler_free(sd->ctrl_handler);
+	media_entity_cleanup(&sd->entity);
+
+	s5c73m3_unregister_spi_driver(state);
+	regulator_bulk_free(S5C73M3_MAX_SUPPLIES, state->supplies);
+	s5c73m3_free_gpios(state);
+
+	return 0;
+}
+
+static const struct i2c_device_id s5c73m3_id[] = {
+	{ DRIVER_NAME, 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, s5c73m3_id);
+
+static struct i2c_driver s5c73m3_i2c_driver = {
+	.driver = {
+		.name	= DRIVER_NAME,
+	},
+	.probe		= s5c73m3_probe,
+	.remove		= __devexit_p(s5c73m3_remove),
+	.id_table	= s5c73m3_id,
+};
+
+module_i2c_driver(s5c73m3_i2c_driver);
+
+MODULE_DESCRIPTION("Samsung S5C73M3 camera driver");
+MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5c73m3/s5c73m3.h b/drivers/media/video/s5c73m3/s5c73m3.h
new file mode 100644
index 0000000..4b03dc0
--- /dev/null
+++ b/drivers/media/video/s5c73m3/s5c73m3.h
@@ -0,0 +1,446 @@
+/*
+ * Samsung LSI S5C73M3 8M pixel camera driver
+ *
+ * Copyright (C) 2012, Samsung Electronics, Co., Ltd.
+ * Sylwester Nawrocki <s.nawrocki@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef S5C73M3_H_
+#define S5C73M3_H_
+
+#include <linux/kernel.h>
+#include <linux/regulator/consumer.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ctrls.h>
+#include <media/v4l2-subdev.h>
+#include <media/s5c73m3.h>
+
+/*
+ * Subdev private controls
+ */
+
+#define V4L2_CID_FIRMWARE_VERSION	(V4L2_CTRL_CLASS_CAMERA | 0x1001)
+/* Capture context */
+#define V4L2_CID_CAPTURE_CTX		(V4L2_CTRL_CLASS_CAMERA | 0x1002)
+enum s5c73m3_capture_ctx {
+	V4L2_CAPTURE_CTX_PREVIEW,
+	V4L2_CAPTURE_CTX_STILL,
+	V4L2_CAPTURE_CTX_CAMCORDER,
+};
+/* Snapshot trigger */
+#define V4L2_CID_SNAPSHOT		(V4L2_CTRL_CLASS_CAMERA | 0x1003)
+/* Flash mode */
+#define V4L2_CID_FLASH_MODE		(V4L2_CTRL_CLASS_CAMERA | 0x1004)
+enum s5c73m3_flash_mode {
+        FLASH_MODE_AUTO,
+	FLASH_MODE_ON,
+	FLASH_MODE_OFF,
+	FLASH_MODE_TORCH,
+};
+
+#define DRIVER_NAME			"S5C73M3"
+#define S5C73M3_FW_FILENAME		"SlimISP.bin"
+
+#define S5C73M3_FW_VER_LEN		22
+#define S5C73M3_FW_VER_FILE_CUR		0x16FF00
+#define S5C73M3_FLASH_BASE_ADDR		0x10000000
+#define S5C73M3_INT_RAM_BASE_ADDR	0x68000000
+
+#define S5C73M3_INTERLEAVED_SIZE_MAX	(8 * SZ_1M)
+#define S5C73M3_JPEG_MAXSIZE		0x800000
+#define S5C73M3_YUV_MAXSIZE		0x3F4800 /*FHD*/
+#define S5C73M3_POINTER_MAXSIZE		0x10E0 /*FHD*/
+
+#define S5C73M3_WIN_WIDTH_MAX		1280
+#define S5C73M3_WIN_HEIGHT_MAX		1024
+#define S5C73M3_WIN_WIDTH_MIN		8
+#define S5C73M3_WIN_HEIGHT_MIN		8
+#define S5C73M3_EMBEDDED_DATA_SIZE	SZ_4K
+
+/* Subdev pad index definitions */
+#define S5C73M3_OUTIF_SOURCE_PAD	0
+#define S5C73M3_JPEG_SINK_PAD		1
+#define S5C73M3_ISP_SINK_PAD		2
+#define S5C73M3_NUM_PADS		3
+
+/*
+ * Register definitions
+ */
+#define S5C73M3_REG(_addrh, _addrl) (((_addrh) << 16) | _addrl)
+
+/*
+ * FIXME: The CMD* register address names are a guess only. They are
+ * analogous to the S5K6AA sensor convention and are by no means
+ * correllated with the (non-existent?) S5C73M3 registers documentation.
+ */
+#define AHB_MSB_ADDR_PTR		0xfcfc
+#define REG_CMDWR_ADDRH			0x0050
+#define REG_CMDWR_ADDRL			0x0054
+#define REG_CMDRD_ADDRH			0x0058
+#define REG_CMDRD_ADDRL			0x005c
+#define REG_CMDBUF_ADDR			0x0f14
+
+#define REG_IMG_OUTPUT			S5C73M3_REG(0, 0x0902)
+#define  REG_IMG_OUTPUT_HDR		0x0008
+#define  REG_IMG_OUTPUT_YUV		0x0009
+#define  REG_IMG_OUTPUT_INTERLEAVED	0x000d
+
+#define REG_STILL_PRE_FLASH		S5C73M3_REG(0, 0x0a00)
+#define  REG_STILL_PRE_FLASH_FIRE	0x0000
+#define  REG_STILL_PRE_FLASH_NON_FIRED	0x0000
+#define  REG_STILL_PRE_FLASH_FIRED	0x0001
+
+#define REG_STILL_MAIN_FLASH		S5C73M3_REG(0, 0x0a02)
+#define  REG_STILL_MAIN_FLASH_CANCEL	0x0001
+#define  REG_STILL_MAIN_FLASH_FIRE	0x0002
+
+#define REG_ZOOM_STEP			S5C73M3_REG(0, 0x0b00)
+
+#define REG_IMAGE_EFFECT		S5C73M3_REG(0, 0x0b0a)
+#define  REG_IMAGE_EFFECT_NONE		0x0001
+#define  REG_IMAGE_EFFECT_NEGATIVE	0x0002
+#define  REG_IMAGE_EFFECT_AQUA		0x0003
+#define  REG_IMAGE_EFFECT_SEPIA		0x0004
+#define  REG_IMAGE_EFFECT_MONO		0x0005
+
+#define REG_IMAGE_QUALITY		S5C73M3_REG(0, 0x0b0c)
+#define  REG_IMAGE_QUALITY_SUPERFINE	0x0000
+#define  REG_IMAGE_QUALITY_FINE		0x0001
+#define  REG_IMAGE_QUALITY_NORMAL	0x0002
+
+#define REG_FLASH_MODE			S5C73M3_REG(0, 0x0b0e)
+#define  REG_FLASH_MODE_OFF		0x0000
+#define  REG_FLASH_MODE_ON		0x0001
+#define  REG_FLASH_MODE_AUTO		0x0002
+
+#define REG_FLASH_STATUS		S5C73M3_REG(0, 0x0b80)
+#define  REG_FLASH_STATUS_OFF		0x0001
+#define  REG_FLASH_STATUS_ON		0x0002
+#define  REG_FLASH_STATUS_AUTO		0x0003
+
+#define REG_FLASH_TORCH			S5C73M3_REG(0, 0x0b12)
+#define  REG_FLASH_TORCH_OFF		0x0000
+#define  REG_FLASH_TORCH_ON		0x0001
+
+#define REG_AE_NEEDS_FLASH		S5C73M3_REG(0, 0x0cba)
+#define  REG_AE_NEEDS_FLASH_OFF		0x0000
+#define  REG_AE_NEEDS_FLASH_ON		0x0001
+
+#define REG_CHG_MODE			S5C73M3_REG(0, 0x0b10)
+#define  CHG_MODE_YUV			0x8000
+#define  CHG_MODE_INTERLEAVED		0x8010
+
+#define  CHG_MODE_YUV_320_240		0x8001
+#define  CHG_MODE_YUV_400_300		0x8002
+#define  CHG_MODE_YUV_640_480		0x8003
+#define  CHG_MODE_YUV_800_600		0x8004
+#define  CHG_MODE_YUV_960_720		0x8005
+#define  CHG_MODE_YUV_1280_720		0x8006
+#define  CHG_MODE_YUV_1280_960		0x8007
+#define  CHG_MODE_YUV_1600_1200		0x8008
+#define  CHG_MODE_YUV_1632_1224		0x8009
+#define  CHG_MODE_YUV_1920_1080		0x800a
+#define  CHG_MODE_YUV_1920_1440		0x800b
+#define  CHG_MODE_YUV_2304_1296		0x800c
+#define  CHG_MODE_YUV_2304_1728		0x800d
+
+#define  CHG_MODE_JPEG_640_480		0x0010
+#define  CHG_MODE_JPEG_800_450		0x0020
+#define  CHG_MODE_JPEG_800_600		0x0030
+#define  CHG_MODE_JPEG_1600_960		0x0040
+#define  CHG_MODE_JPEG_1600_1200	0x0050
+#define  CHG_MODE_JPEG_2048_1152	0x0060
+#define  CHG_MODE_JPEG_2048_1536	0x0070
+#define  CHG_MODE_JPEG_2560_1440	0x0080
+#define  CHG_MODE_JPEG_2560_1920	0x0090
+#define  CHG_MODE_JPEG_3072_1728	0x00a0
+#define  CHG_MODE_JPEG_3264_2304	0x00b0
+#define  CHG_MODE_JPEG_3264_1836	0x00c0
+#define  CHG_MODE_JPEG_3264_2448	0x00d0
+
+#define REG_AF_CON			S5C73M3_REG(0, 0x0e00)
+#define  REG_AF_CON_STOP		0x0000
+#define  REG_AF_CON_SCAN		0x0001 /* AF_SCAN: Full Search */
+#define  REG_AF_CON_START		0x0002 /* AF_START: Fast Search */
+
+#define REG_AF_CAL			S5C73M3_REG(0, 0x0e06)
+#define REG_AF_TOUCH_AF			S5C73M3_REG(0, 0x0e0a)
+
+#define REG_AF_STATUS			S5C73M3_REG(0x0009, 0x5e80)
+#define  REG_CAF_STATUS_FIND_SEARCH_DIR 0x0001
+#define  REG_CAF_STATUS_FOCUSING	0x0002
+#define  REG_CAF_STATUS_FOCUSED		0x0003
+#define  REG_CAF_STATUS_UNFOCUSED	0x0004
+#define  REG_AF_STATUS_INVALID		0x0010
+#define  REG_AF_STATUS_FOCUSING		0x0020
+#define  REG_AF_STATUS_FOCUSED		0x0030
+#define  REG_AF_STATUS_UNFOCUSED	0x0040
+
+#define REG_AF_TOUCH_POSITION		S5C73M3_REG(0, 0x5e8e)
+#define REG_AF_FACE_ZOOM		S5C73M3_REG(0, 0x0e10)
+
+#define REG_AF_MODE			S5C73M3_REG(0, 0x0e02)
+#define  REG_AF_MODE_NORMAL		0x0000
+#define  REG_AF_MODE_MACRO		0x0001
+#define  REG_AF_MODE_MOVIE_CAF_START	0x0002
+#define  REG_AF_MODE_MOVIE_CAF_STOP	0x0003
+#define  REG_AF_MODE_PREVIEW_CAF_START	0x0004
+#define  REG_AF_MODE_PREVIEW_CAF_STOP	0x0005
+
+#define REG_AF_SOFTLANDING		S5C73M3_REG(0, 0x0e16)
+#define  REG_AF_SOFTLANDING_ON		0x0000
+
+#define REG_FACE_DET			S5C73M3_REG(0, 0x0e0c)
+#define  REG_FACE_DET_OFF		0x0000
+#define  REG_FACE_DET_ON		0x0001
+
+#define REG_FACE_DET_OSD		S5C73M3_REG(0, 0x0e0e)
+#define  REG_FACE_DET_OSD_OFF		0x0000
+#define  REG_FACE_DET_OSD_ON		0x0001
+
+#define REG_AE_CON			S5C73M3_REG(0, 0x0c00)
+#define  REG_AE_STOP			0x0000 /* lock */
+#define  REG_AE_START			0x0001 /* unlock */
+
+#define REG_ISO				S5C73M3_REG(0, 0x0c02)
+#define  REG_ISO_AUTO			0x0000
+#define  REG_ISO_100			0x0001
+#define  REG_ISO_200			0x0002
+#define  REG_ISO_400			0x0003
+#define  REG_ISO_800			0x0004
+#define  REG_ISO_SPORTS			0x0005
+#define  REG_ISO_NIGHT			0x0006
+#define  REG_ISO_INDOOR			0x0007
+
+/* 0x00000 (-2.0 EV)...0x0008 (2.0 EV), 0.5EV step */
+#define REG_EV				S5C73M3_REG(0, 0x0c04)
+
+#define REG_METERING			S5C73M3_REG(0, 0x0c06)
+#define  REG_METERING_CENTER		0x0000
+#define  REG_METERING_SPOT		0x0001
+#define  REG_METERING_AVERAGE		0x0002
+#define  REG_METERING_SMART		0x0003
+
+#define REG_WDR				S5C73M3_REG(0, 0x0c08)
+#define  REG_WDR_OFF			0x0000
+#define  REG_WDR_ON			0x0001
+
+#define REG_AE_MODE			S5C73M3_REG(0, 0x0c1e)
+#define  REG_AE_MODE_AUTO_SET		0x0000
+#define  REG_AE_MODE_FIXED_30FPS	0x0002
+#define  REG_AE_MODE_FIXED_20FPS	0x0003
+#define  REG_AE_MODE_FIXED_15FPS	0x0004
+#define  REG_AE_MODE_FIXED_120FPS	0x0008
+#define  REG_AE_MODE_FIXED_7FPS		0x0009
+#define  REG_AE_MODE_ANTI_SHAKE		0x0013
+
+/* 0x0000...0x0004 -> sharpness: 0, 1, 2, -1, -2 */
+#define REG_SHARPNESS			S5C73M3_REG(0, 0x0c14)
+
+/* 0x0000...0x0004 -> saturation: 0, 1, 2, -1, -2 */
+#define REG_SATURATION			S5C73M3_REG(0, 0x0c16)
+
+/* 0x0000...0x0004 -> contrast: 0, 1, 2, -1, -2 */
+#define REG_CONTRAST			S5C73M3_REG(0, 0x0c18)
+
+#define REG_SCENE_MODE			S5C73M3_REG(0, 0x0c1a)
+#define  REG_SCENE_MODE_NONE		0x0000
+#define  REG_SCENE_MODE_PORTRAIT	0x0001
+#define  REG_SCENE_MODE_LANDSCAPE	0x0002
+#define  REG_SCENE_MODE_SPORTS		0x0003
+#define  REG_SCENE_MODE_INDOOR		0x0004
+#define  REG_SCENE_MODE_BEACH		0x0005
+#define  REG_SCENE_MODE_SUNSET		0x0006
+#define  REG_SCENE_MODE_DAWN		0x0007
+#define  REG_SCENE_MODE_FALL		0x0008
+#define  REG_SCENE_MODE_NIGHT		0x0009
+#define  REG_SCENE_MODE_AGAINST_LIGHT	0x000a
+#define  REG_SCENE_MODE_FIRE		0x000b
+#define  REG_SCENE_MODE_TEXT		0x000c
+#define  REG_SCENE_MODE_CANDLE		0x000d
+
+#define REG_AE_AUTO_BRACKET		S5C73M3_REG(0, 0x0b14)
+#define  REG_AE_AUTO_BRAKET_EV05	0x0080
+#define  REG_AE_AUTO_BRAKET_EV10	0x0100
+#define  REG_AE_AUTO_BRAKET_EV15	0x0180
+#define  REG_AE_AUTO_BRAKET_EV20	0x0200
+
+#define REG_SENSOR_STREAMING		S5C73M3_REG(0, 0x090a)
+#define  REG_SENSOR_STREAMING_OFF	0x0000
+#define  REG_SENSOR_STREAMING_ON	0x0001
+
+#define REG_AWB_MODE			S5C73M3_REG(0, 0x0d02)
+#define  REG_AWB_MODE_INCANDESCENT	0x0000
+#define  REG_AWB_MODE_FLUORESCENT1	0x0001
+#define  REG_AWB_MODE_FLUORESCENT2	0x0002
+#define  REG_AWB_MODE_DAYLIGHT		0x0003
+#define  REG_AWB_MODE_CLOUDY		0x0004
+#define  REG_AWB_MODE_AUTO		0x0005
+
+#define REG_AWB_CON			S5C73M3_REG(0, 0x0d00)
+#define  REG_AWB_STOP			0x0000 /* lock */
+#define  REG_AWB_START			0x0001 /* unlock */
+
+#define S5C73M3_ARRAY_END		0xffffffff
+
+#define S5C73M3_MAX_SUPPLIES 		6
+
+struct s5c73m3_ctrls {
+	struct v4l2_ctrl_handler handler;
+	struct {
+		/* exposure/exposure bias cluster */
+		struct v4l2_ctrl *auto_exposure;
+		struct v4l2_ctrl *exposure_bias;
+		struct v4l2_ctrl *exposure_metering;
+	};
+	struct {
+		/* iso/auto iso cluster */
+		struct v4l2_ctrl *auto_iso;
+		struct v4l2_ctrl *iso;
+	};
+	struct {
+		/* white bal. preset/auto white bal. cluster */
+		struct v4l2_ctrl *auto_wb;
+		struct v4l2_ctrl *wb_preset;
+	};
+	struct {
+		/* continuous auto focus/auto focus cluster */
+		struct v4l2_ctrl *focus_auto;
+		struct v4l2_ctrl *af_start;
+		struct v4l2_ctrl *af_stop;
+		struct v4l2_ctrl *af_status;
+		struct v4l2_ctrl *af_distance;
+		struct v4l2_ctrl *af_area;
+	};
+
+	struct v4l2_ctrl *ae_awb_lock;
+	struct v4l2_ctrl *colorfx;
+	struct v4l2_ctrl *contrast;
+	struct v4l2_ctrl *saturation;
+	struct v4l2_ctrl *sharpness;
+	struct v4l2_ctrl *zoom;
+	struct v4l2_ctrl *wdr;
+	struct v4l2_ctrl *stabilization;
+	struct v4l2_ctrl *jpeg_quality;
+	struct v4l2_ctrl *flash_mode;
+	struct v4l2_ctrl *scene_mode;
+	struct v4l2_ctrl *capture_ctx;
+	struct v4l2_ctrl *snapshot;
+};
+
+enum s5c73m3_gpio_id {
+	STBY,
+	RST,
+	GPIO_NUM,
+};
+
+struct s5c73m3_focus {
+	unsigned short pos_x;
+	unsigned short pos_y;
+};
+
+struct s5c73m3_pixfmt {
+	enum v4l2_mbus_pixelcode code;
+	u32 colorspace;
+	u8  mipi_data_type;
+};
+
+struct s5c73m3_interval {
+	u16 fps_reg;
+	struct v4l2_fract interval;
+	/* Maximum rectangle for the interval */
+	struct v4l2_frmsize_discrete size;
+};
+
+struct s5c73m3 {
+	struct v4l2_subdev subdev;
+	struct media_pad pads[S5C73M3_NUM_PADS];
+
+	struct spi_driver spidrv;
+	struct spi_device *spi_dev;
+	struct i2c_client *i2c_client;
+
+	struct regulator_bulk_data supplies[S5C73M3_MAX_SUPPLIES];
+	struct s5c73m3_gpio gpio[GPIO_NUM];
+
+	/* External master clock frequency */
+	unsigned long mclk_frequency;
+	/* Video bus type - MIPI-CSI2/paralell */
+	enum v4l2_mbus_type bus_type;
+
+	const struct s5c73m3_frame_size *pix_sizes[2];
+#define PREVIEW_IDX 0
+#define CAPTURE_IDX 1
+	unsigned int pix_sizes_len[2];
+
+	const struct s5c73m3_frame_size *prev_pix_size;
+	const struct s5c73m3_frame_size *cap_pix_size;
+	u8 wide_res;
+
+	const struct s5c73m3_interval *fiv;
+
+	/* protects the struct members below */
+	struct mutex lock;
+
+	int fw_index;
+
+	struct s5c73m3_ctrls ctrls;
+	struct v4l2_mbus_framefmt format[2];
+
+	u8 streaming;
+	u8 apply_fmt;
+	u8 apply_crop;
+	u8 apply_ctrls;
+	u8 apply_fiv;
+	u8 isp_ready;
+
+	struct s5c73m3_focus focus;
+
+	unsigned short fw_error;
+	unsigned short power;
+
+	char sensor_fw[10];
+};
+
+struct s5c73m3_frame_size {
+	u32 width;
+	u32 height;
+	u8 reg_val;
+	/* Wide resolution is set to 1 : height / width < 0.65 */
+	u8 wide_res; /* for POSTVIEW only */
+};
+
+extern int s5c73m3_dbg;
+
+/*
+ * Function prototypes
+ */
+int s5c73m3_register_spi_driver(struct s5c73m3 *state);
+void s5c73m3_unregister_spi_driver(struct s5c73m3 *state);
+int s5c73m3_spi_write(struct s5c73m3 *state, const void *addr,
+		      const unsigned int len, const unsigned int tx_size);
+
+int s5c73m3_i2c_write(struct i2c_client *client, u16 addr, u16 data);
+int s5c73m3_read(struct i2c_client *client, u32 addr, u16 *data);
+int s5c73m3_write_cmd(struct s5c73m3 *state, u32 addr, u16 data);
+int s5c73m3_init_controls(struct s5c73m3 *state);
+
+static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
+{
+	return &container_of(ctrl->handler, struct s5c73m3,
+			     ctrls.handler)->subdev;
+}
+
+static inline struct s5c73m3 *subdev_to_s5c73m3(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct s5c73m3, subdev);
+}
+#endif	/* S5C73M3_H_ */
diff --git a/include/media/s5c73m3.h b/include/media/s5c73m3.h
new file mode 100644
index 0000000..9110861
--- /dev/null
+++ b/include/media/s5c73m3.h
@@ -0,0 +1,62 @@
+/*
+ * Driver for S5C73M3
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+#ifndef MEDIA_S5C73M3__
+#define MEDIA_S5C73M3__
+
+#include <linux/videodev2.h>
+#include <media/v4l2-mediabus.h>
+
+/**
+ * struct s5c73m3_gpio - data structure describing a GPIO
+ * @gpio:  GPIO number
+ * @level: indicates active state of the @gpio
+ */
+struct s5c73m3_gpio {
+	int gpio;
+	int level;
+};
+
+/**
+ * struct s5c73m3_platform_data - s5c73m3 driver platform data
+ * @mclk_frequency: sensor's master clock frequency in Hz
+ * @gpio_reset:  GPIO driving RESET pin
+ * @gpio_stby:   GPIO driving STBY pin
+ * @nlanes:      maximum number of MIPI-CSI lanes used
+ * @horiz_flip:  default horizontal image flip value, non zero to enable
+ * @vert_flip:   default vertical image flip value, non zero to enable
+ */
+
+struct s5c73m3_platform_data {
+	unsigned long mclk_frequency;
+
+	struct s5c73m3_gpio gpio_reset;
+	struct s5c73m3_gpio gpio_stby;
+
+	enum v4l2_mbus_type bus_type;
+	u8 nlanes;
+	u8 horiz_flip;
+	u8 vert_flip;
+};
+
+#define V4L2_CID_CAM_SENSOR_FW_VER (V4L2_CID_CAMERA_CLASS_BASE + 28)
+#define V4L2_CID_CAM_PHONE_FW_VER (V4L2_CID_CAMERA_CLASS_BASE + 29)
+
+enum stream_mode_t {
+	STREAM_MODE_CAM_OFF,
+	STREAM_MODE_CAM_ON,
+	STREAM_MODE_MOVIE_OFF,
+	STREAM_MODE_MOVIE_ON,
+};
+
+#define V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT	(V4L2_CID_CAMERA_CLASS_BASE+37)
+#define V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP	(V4L2_CID_CAMERA_CLASS_BASE+38)
+#define V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH	(V4L2_CID_CAMERA_CLASS_BASE+39)
+#define V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT	(V4L2_CID_CAMERA_CLASS_BASE+40)
+
+#endif /* MEDIA_S5C73M3__ */
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH 15/15] vivi: Add controls
  2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
                   ` (13 preceding siblings ...)
  2012-04-17 10:09 ` [PATCH 14/15] V4L: Add S5C73M3 sensor sub-device driver Sylwester Nawrocki
@ 2012-04-17 10:09 ` Sylwester Nawrocki
  14 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 10:09 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, s.nawrocki,
	Kyungmin Park

This patch is just for testing the new controls, it is NOT
intended for merging upstream.

Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/media/video/vivi.c |  111 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 110 insertions(+), 1 deletion(-)

diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index d75a1e4..3404ae1 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -179,6 +179,29 @@ struct vivi_dev {
 	struct v4l2_ctrl	   *bitmask;
 	struct v4l2_ctrl	   *int_menu;
 
+	struct v4l2_ctrl	   *exposure_bias;
+	struct v4l2_ctrl	   *metering;
+	struct v4l2_ctrl	   *wb_preset;
+	struct {
+		/* iso/auto iso cluster */
+		struct v4l2_ctrl  *auto_iso;
+		struct v4l2_ctrl  *iso;
+	};
+	struct {
+		/* continuous auto focus/auto focus cluster */
+		struct v4l2_ctrl  *focus_auto;
+		struct v4l2_ctrl  *af_start;
+		struct v4l2_ctrl  *af_stop;
+		struct v4l2_ctrl  *af_status;
+		struct v4l2_ctrl  *af_distance;
+		struct v4l2_ctrl  *af_area;
+	};
+	struct v4l2_ctrl	  *scene_mode;
+	struct v4l2_ctrl	  *lock_3a;
+	struct v4l2_ctrl	  *colorfx;
+	struct v4l2_ctrl	  *wdr;
+	struct v4l2_ctrl	  *stabilization;
+
 	spinlock_t                 slock;
 	struct mutex		   mutex;
 
@@ -208,6 +231,14 @@ struct vivi_dev {
 	u8 			   line[MAX_WIDTH * 4];
 };
 
+static const s64 vivi_iso_qmenu[] = {
+	50, 100, 200, 400, 800, 1600
+};
+
+static const s64 vivi_ev_bias_qmenu[] = {
+	-1500, -1000, -500, 0, 500, 1000, 1500
+};
+
 /* ------------------------------------------------------------------
 	DMA and thread functions
    ------------------------------------------------------------------*/
@@ -516,6 +547,10 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
 		gen_text(dev, vbuf, line++ * 16, 16, str);
 	}
 
+	snprintf(str, sizeof(str), " auto iso: %s, iso: %lld ",
+		 dev->auto_iso->cur.val ? "on" : "off",
+		 vivi_iso_qmenu[dev->iso->cur.val]);
+
 	dev->mv_count += 2;
 
 	buf->vb.v4l2_buf.field = dev->field;
@@ -1023,6 +1058,13 @@ static int vivi_s_ctrl(struct v4l2_ctrl *ctrl)
 
 	if (ctrl == dev->button)
 		dev->button_pressed = 30;
+
+	if (ctrl->type == V4L2_CTRL_TYPE_STRING)
+		return 0;
+
+	dprintk(dev, 1, "%s: control: %s, val: %d, val64: %lld",
+		__func__, ctrl->name, ctrl->val, ctrl->val64);
+
 	return 0;
 }
 
@@ -1274,7 +1316,8 @@ static int __init vivi_create_instance(int inst)
 	dev->width = 640;
 	dev->height = 480;
 	hdl = &dev->ctrl_handler;
-	v4l2_ctrl_handler_init(hdl, 11);
+	v4l2_ctrl_handler_init(hdl, 26);
+
 	dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
 			V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
 	dev->brightness = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
@@ -1297,11 +1340,77 @@ static int __init vivi_create_instance(int inst)
 	dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL);
 	dev->bitmask = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_bitmask, NULL);
 	dev->int_menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int_menu, NULL);
+
+	dev->wb_preset = v4l2_ctrl_new_std_menu(hdl,
+			&vivi_ctrl_ops, V4L2_CID_WHITE_BALANCE_PRESET,
+			7, ~0xfe, V4L2_WHITE_BALANCE_PRESET_DAYLIGHT);
+
+	dev->exposure_bias = v4l2_ctrl_new_std_int_menu(hdl,
+			&vivi_ctrl_ops, V4L2_CID_AUTO_EXPOSURE_BIAS,
+			ARRAY_SIZE(vivi_ev_bias_qmenu) - 1,
+			ARRAY_SIZE(vivi_ev_bias_qmenu)/2 - 1,
+			vivi_ev_bias_qmenu);
+
+	dev->metering = v4l2_ctrl_new_std_menu(hdl,
+			&vivi_ctrl_ops, V4L2_CID_EXPOSURE_METERING,
+			2, ~0x7, V4L2_EXPOSURE_METERING_AVERAGE);
+
+	/* ISO cluster */
+	dev->auto_iso = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
+			V4L2_CID_ISO_SENSITIVITY_AUTO, 0, 1, 1, 1);
+
+	dev->iso = v4l2_ctrl_new_std_int_menu(hdl, &vivi_ctrl_ops,
+			V4L2_CID_ISO_SENSITIVITY, ARRAY_SIZE(vivi_iso_qmenu) - 1,
+			ARRAY_SIZE(vivi_iso_qmenu)/2 - 1, vivi_iso_qmenu);
+
+	/* Auto focus cluster */
+	dev->focus_auto = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
+			V4L2_CID_FOCUS_AUTO, 0, 1, 1, 0);
+
+	dev->af_start = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
+			V4L2_CID_AUTO_FOCUS_START, 0, 1, 1, 0);
+
+	dev->af_stop = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
+			V4L2_CID_AUTO_FOCUS_STOP, 0, 1, 1, 0);
+
+	dev->af_status = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
+			V4L2_CID_AUTO_FOCUS_STATUS, 0, 0x07, 0, 0);
+
+	dev->af_distance = v4l2_ctrl_new_std_menu(hdl, &vivi_ctrl_ops,
+			V4L2_CID_AUTO_FOCUS_DISTANCE,
+			2, 0, V4L2_AUTO_FOCUS_DISTANCE_NORMAL);
+
+	dev->af_area = v4l2_ctrl_new_std_menu(hdl, &vivi_ctrl_ops,
+			V4L2_CID_AUTO_FOCUS_AREA, 1, 0,
+			V4L2_AUTO_FOCUS_AREA_ALL);
+
+	dev->colorfx = v4l2_ctrl_new_std_menu(hdl, &vivi_ctrl_ops,
+			V4L2_CID_COLORFX, 15, 0, V4L2_COLORFX_NONE);
+
+	dev->wdr = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
+			V4L2_CID_WIDE_DYNAMIC_RANGE, 0, 1, 1, 0);
+
+	dev->stabilization = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
+			V4L2_CID_IMAGE_STABILIZATION, 0, 1, 1, 0);
+
+	dev->lock_3a = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
+			V4L2_CID_3A_LOCK, 0, 0x7, 0, 0);
+
+	dev->scene_mode = v4l2_ctrl_new_std_menu(hdl, &vivi_ctrl_ops,
+			V4L2_CID_SCENE_MODE, 13, ~0x1fff,
+			V4L2_SCENE_MODE_NONE);
+
 	if (hdl->error) {
 		ret = hdl->error;
 		goto unreg_dev;
 	}
 	v4l2_ctrl_auto_cluster(2, &dev->autogain, 0, true);
+
+	v4l2_ctrl_auto_cluster(2, &dev->auto_iso, 0, false);
+	dev->af_status->flags |= V4L2_CTRL_FLAG_VOLATILE;
+	v4l2_ctrl_cluster(6, &dev->focus_auto);
+	dev->lock_3a->flags |= V4L2_CTRL_FLAG_VOLATILE;
+
 	dev->v4l2_dev.ctrl_handler = hdl;
 
 	/* initialize locks */
-- 
1.7.10


^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH 01/15] V4L: Extend V4L2_CID_COLORFX with more image effects
  2012-04-17 10:09 ` [PATCH 01/15] V4L: Extend V4L2_CID_COLORFX with more image effects Sylwester Nawrocki
@ 2012-04-17 10:51   ` Rémi Denis-Courmont
  2012-04-17 11:28     ` Sylwester Nawrocki
  0 siblings, 1 reply; 27+ messages in thread
From: Rémi Denis-Courmont @ 2012-04-17 10:51 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: linux-media, laurent.pinchart, sakari.ailus, g.liakhovetski,
	hdegoede, moinejf, m.szyprowski, riverful.kim, sw0312.kim,
	Kyungmin Park

On Tue, 17 Apr 2012 12:09:42 +0200, Sylwester Nawrocki

<s.nawrocki@samsung.com> wrote:

> This patch adds definition of additional color effects:

>  - V4L2_COLORFX_AQUA,

>  - V4L2_COLORFX_ART_FREEZE,

>  - V4L2_COLORFX_SILHOUETTE,

>  - V4L2_COLORFX_SOLARIZATION,

>  - V4L2_COLORFX_ANTIQUE,



There starts to be a lot of different color effects with no obvious way to

determine which ones the current device actually suppots. Should this not

be a menu control instead?



>  - V4L2_COLORFX_ARBITRARY.

>

> The control's type in the documentation is changed from 'enum' to 'menu'

> - V4L2_CID_COLORFX has always been a menu, not an integer type control.

> 

> The V4L2_COLORFX_ARBITRARY option enables custom color effects, which

are

> impossible or impractical to define as the menu items. For example, the

> devices may provide coefficients for Cb and Cr manipulation, which yield

> many permutations, e.g. many slightly different color tints. Such

devices

> are better exporting their own API for precise control of non-standard

> color effects.



I don't understand why you need a number for this, if it's going to use

another control anyway... ?



-- 

Rémi Denis-Courmont

Sent from my collocated server

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 01/15] V4L: Extend V4L2_CID_COLORFX with more image effects
  2012-04-17 10:51   ` Rémi Denis-Courmont
@ 2012-04-17 11:28     ` Sylwester Nawrocki
  2012-04-22 16:00       ` Sylwester Nawrocki
  0 siblings, 1 reply; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-17 11:28 UTC (permalink / raw)
  To: Rémi Denis-Courmont
  Cc: linux-media, laurent.pinchart, sakari.ailus, g.liakhovetski,
	hdegoede, moinejf, m.szyprowski, riverful.kim, sw0312.kim,
	Kyungmin Park

On 04/17/2012 12:51 PM, Rémi Denis-Courmont wrote:
> On Tue, 17 Apr 2012 12:09:42 +0200, Sylwester Nawrocki
> <s.nawrocki@samsung.com> wrote:
>> This patch adds definition of additional color effects:
>>  - V4L2_COLORFX_AQUA,
>>  - V4L2_COLORFX_ART_FREEZE,
>>  - V4L2_COLORFX_SILHOUETTE,
>>  - V4L2_COLORFX_SOLARIZATION,
>>  - V4L2_COLORFX_ANTIQUE,
> 
> There starts to be a lot of different color effects with no obvious way to
> determine which ones the current device actually suppots. Should this not
> be a menu control instead?

Fortunately this has been a menu control, since it was introduced. Only 
the DocBook erroneously defined it as an enum. This patch also fixes that, 
please see the DocBook part.

>>  - V4L2_COLORFX_ARBITRARY.
>>
>> The control's type in the documentation is changed from 'enum' to 'menu'
>> - V4L2_CID_COLORFX has always been a menu, not an integer type control.
>>
>> The V4L2_COLORFX_ARBITRARY option enables custom color effects, which
> are
>> impossible or impractical to define as the menu items. For example, the
>> devices may provide coefficients for Cb and Cr manipulation, which yield
>> many permutations, e.g. many slightly different color tints. Such
> devices
>> are better exporting their own API for precise control of non-standard
>> color effects.
> 
> I don't understand why you need a number for this, if it's going to use
> another control anyway... ?

In my use case, the hardware has 3 registers: one of them selects the colour
effect and two others determine Cr, Cb coefficients (probably I could use
V4L2_CID_RED_BALANCE, V4L2_CID_BLUE_BALANCE for that, but so far these are 
just private controls). 

If I would have removed the V4L2_COLORFX_ARBITRARY item, another control
would have to be added (let's say boolean V4L2_PRIV_IMG_EFFECT). Just to 
enable the "arbitrary" effect. 

Then, to enable the arbitrary effect V4L2_CID_COLORFX would have to be set
to V4L2_COLORFX_NONE, nnd V4L2_PRIV_IMG_EFFECT to true.

The CB, CR coefficients are meaningful only when the arbitrary effect is
selected. So having another option in the menu, which drivers can just mask
if they don't support it, appeared better to me. 

It's a bit similar to gain/autogain scenario, where gain is active only when
autogain is off.
Maybe I should just add another private control (V4L2_PRIV_IMG_EFFECT) and
remove V4L2_COLORFX_ARBITRARY item.


---
Thanks,
Sylwester

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 04/15] V4L: Add camera white balance preset control
  2012-04-17 10:09 ` [PATCH 04/15] V4L: Add camera white balance preset control Sylwester Nawrocki
@ 2012-04-17 13:23   ` Hans de Goede
  2012-04-18  8:46     ` Sylwester Nawrocki
  0 siblings, 1 reply; 27+ messages in thread
From: Hans de Goede @ 2012-04-17 13:23 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: linux-media, laurent.pinchart, sakari.ailus, g.liakhovetski,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, Kyungmin Park

Hi,

On 04/17/2012 12:09 PM, Sylwester Nawrocki wrote:
> Add V4L2_CID_WHITE_BALANCE_PRESET control for camera white balance
> presets. The following items are defined:
>
>   - V4L2_WHITE_BALANCE_NONE,
>   - V4L2_WHITE_BALANCE_INCANDESCENT,
>   - V4L2_WHITE_BALANCE_FLUORESCENT,
>   - V4L2_WHITE_BALANCE_HORIZON,
>   - V4L2_WHITE_BALANCE_DAYLIGHT,
>   - V4L2_WHITE_BALANCE_FLASH,
>   - V4L2_WHITE_BALANCE_CLOUDY,
>   - V4L2_WHITE_BALANCE_SHADE,
>
> This is a manual white balance control, in addition to V4L2_CID_RED_BALANCE,
> V4L2_CID_BLUE_BALANCE and V4L2_CID_WHITE_BALANCE_TEMPERATURE. It's useful
> for camera devices running more complex firmware and exposing white balance
> preset selection in their user register interface.

Hmm, how is this supposed to work together with the v4l2-ctrls framework?
The framework has a concept of a master control, which has a manual value,
and the slave controls will only get unlocked (V4L2_CTRL_FLAG_INACTIVE
will be cleared) when that master control is set at its manual value, now lets
say that we've V4L2_CID_AUTO_WHITE_BALANCE as master with
V4L2_CID_WHITE_BALANCE_PRESET and V4L2_CID_RED_BALANCE and V4L2_CID_BLUE_BALANCE
slaves. Then when the master control changes from auto to manual all 3 will
have their inactive flag cleared, but if the preset value != V4L2_WHITE_BALANCE_NONE
then the red- and blue-balance should have kept their inactive flag. And since this
clearing of the inactive flag is done after v4l2-ctrls.c has called into the driver
there is no way for the driver to fix this.

One could work-around this by not specifying the whitebalance control cluster as
being an auto cluster, and doing all the auto cluster stuff from the driver, but
that significantly complicates the driver, and we are trying to get away of every
driver doing this kinda stuff for itself...

I still believe that the solution I came up with for pwc is better, the auto
whitebalance control really is a tri state when you add presets whitebalance
is controlled through one of this 3 options:
1) auto
2) preset
3) manual

I know you are worried about having a V4L2_CID_AUTO_WHITE_BALANCE control
which is not a boolean breaking apps, well the pwc driver is a quite popular
driver and I've had 0 bug reports about my turning it into a menu...

Alternatively we could add a new V4L2_CID_WHITE_BALANCE_MENU control and use
that for drivers which have presets rather then the old V4L2_CID_AUTO_WHITE_BALANCE
to ensure that userspace won't trip over it being a menu all of a sudden, but
I believe that it is really important to properly reflect the tri-state nature
of the awb once presets come into play, rather then trying to bolt something
on top of / to the side of our current bi-state control. And I hope that my above
example of what sort of troubles using the bolt-on solution will give, clearly
demonstrates that the bolt-on solution is a bad idea.

Regards,

Hans



>
> Signed-off-by: HeungJun Kim<riverful.kim@samsung.com>
> Signed-off-by: Sylwester Nawrocki<s.nawrocki@samsung.com>
> Signed-off-by: Kyungmin Park<kyungmin.park@samsung.com>
> ---
>   Documentation/DocBook/media/v4l/controls.xml |   68 ++++++++++++++++++++++++++
>   drivers/media/video/v4l2-ctrls.c             |   16 ++++++
>   include/linux/videodev2.h                    |   12 +++++
>   3 files changed, 96 insertions(+)
>
> diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
> index 69363dc..0ee3e9c 100644
> --- a/Documentation/DocBook/media/v4l/controls.xml
> +++ b/Documentation/DocBook/media/v4l/controls.xml
> @@ -3013,6 +3013,74 @@ camera sensor on or off, or specify its strength. Such band-stop filters can
>   be used, for example, to filter out the fluorescent light component.</entry>
>   	</row>
>   	<row><entry></entry></row>
> +
> +	<row id="v4l2-white-balance-preset">
> +	<entry spanname="id"><constant>V4L2_CID_WHITE_BALANCE_PRESET</constant>&nbsp;</entry>
> +	<entry>enum&nbsp;v4l2_white_balance_preset</entry>
> +	</row><row><entry spanname="descr">Sets a predefined white balance
> +configuration. The presets determine color temperature of the light on a basis
> +of which the camera performs white balance adjustments, in order to obtain most
> +accurate color representation. This control has no effect when automatic white
> +balance adjustments are enabled, i.e.<constant>V4L2_CID_AUTO_WHITE_BALANCE
> +</constant>  control is set to<constant>TRUE</constant>  (1). The following white
> +balance presets are listed in order of increasing color temperature.</entry>
> +	</row>
> +	<row>
> +	<entrytbl spanname="descr" cols="2">
> +	<tbody valign="top">
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_PRESET_NONE</constant>&nbsp;</entry>
> +		<entry>None of the presets is active, i.e. the white balance
> +preset feature is disabled. It is useful when driver exposes other manual white
> +balance controls, like<constant>V4L2_CID_RED_BALANCE</constant>  and<constant>
> +V4L2_CID_BLUE_BALANCE</constant>, that may render a configured preset invalid.
> +</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_PRESET_INCANDESCENT</constant>&nbsp;</entry>
> +		<entry>White balance settings for incandescent (tungsten) lighting.
> +It generally cools down the colors and corresponds approximately to 2500...3500 K
> +color temperature range.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_PRESET_FLUORESCENT</constant>&nbsp;</entry>
> +		<entry>With this setting the camera will compensate for fluorescent
> +lighting. It corresponds approximately to 4000...5000 K color temperature.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_PRESET_HORIZON</constant>&nbsp;</entry>
> +		<entry>White balance settings for horizon daylight.
> +This corresponds approximately to 5000 K color temperature.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_PRESET_DAYLIGHT</constant>&nbsp;</entry>
> +		<entry>White balance settings for daylight (with clear sky).
> +This corresponds approximately to 5000...6500 K color temperature.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_PRESET_FLASH</constant>&nbsp;</entry>
> +		<entry>With this setting the camera will compensate for the flash
> +light. It slightly warms up the colors and corresponds roughly to 5000...5500 K
> +color temperature.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_PRESET_CLOUDY</constant>&nbsp;</entry>
> +		<entry>White balance settings for moderately overcast sky.
> +This option corresponds approximately to 6500...8000 K color temperature range
> +and will make colors appear warmer than with the
> +<constant>V4L2_WHITE_BALANCE_PRESET_DAYLIGHT</constant>  preset.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_PRESET_SHADE</constant>&nbsp;</entry>
> +		<entry>White balance settings for shade or heavily overcast
> +sky. It corresponds approximately to 9000...10000 K color temperature.
> +</entry>
> +		</row>
> +	</tbody>
> +	</entrytbl>
> +	</row>
> +	<row><entry></entry></row>
> +
>   	</tbody>
>         </tgroup>
>       </table>
> diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
> index 1f67bf2..b6cd147 100644
> --- a/drivers/media/video/v4l2-ctrls.c
> +++ b/drivers/media/video/v4l2-ctrls.c
> @@ -249,6 +249,17 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
>   		"Arbitrary",
>   		NULL
>   	};
> +	static const char * const white_balance_preset[] = {
> +		"None",
> +		"Incandescent",
> +		"Fluorescent",
> +		"Horizon",
> +		"Daylight",
> +		"Flash",
> +		"Cloudy",
> +		"Shade",
> +		NULL,
> +	};
>   	static const char * const tune_preemphasis[] = {
>   		"No Preemphasis",
>   		"50 useconds",
> @@ -418,6 +429,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
>   		return camera_exposure_auto;
>   	case V4L2_CID_COLORFX:
>   		return colorfx;
> +	case V4L2_CID_WHITE_BALANCE_PRESET:
> +		return white_balance_preset;
>   	case V4L2_CID_TUNE_PREEMPHASIS:
>   		return tune_preemphasis;
>   	case V4L2_CID_FLASH_LED_MODE:
> @@ -605,6 +618,8 @@ const char *v4l2_ctrl_get_name(u32 id)
>   	case V4L2_CID_IRIS_RELATIVE:		return "Iris, Relative";
>   	case V4L2_CID_AUTO_EXPOSURE_BIAS:	return "Auto Exposure, Bias";
>
> +	case V4L2_CID_WHITE_BALANCE_PRESET:	return "White Balance, Preset";
> +
>   	/* FM Radio Modulator control */
>   	/* Keep the order of the 'case's the same as in videodev2.h! */
>   	case V4L2_CID_FM_TX_CLASS:		return "FM Radio Modulator Controls";
> @@ -727,6 +742,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
>   	case V4L2_CID_MPEG_STREAM_VBI_FMT:
>   	case V4L2_CID_EXPOSURE_AUTO:
>   	case V4L2_CID_COLORFX:
> +	case V4L2_CID_WHITE_BALANCE_PRESET:
>   	case V4L2_CID_TUNE_PREEMPHASIS:
>   	case V4L2_CID_FLASH_LED_MODE:
>   	case V4L2_CID_FLASH_STROBE_SOURCE:
> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> index fd2f400..537663a 100644
> --- a/include/linux/videodev2.h
> +++ b/include/linux/videodev2.h
> @@ -1729,6 +1729,18 @@ enum  v4l2_exposure_auto_type {
>
>   #define V4L2_CID_AUTO_EXPOSURE_BIAS		(V4L2_CID_CAMERA_CLASS_BASE+19)
>
> +#define V4L2_CID_WHITE_BALANCE_PRESET		(V4L2_CID_CAMERA_CLASS_BASE+20)
> +enum v4l2_white_balance_preset {
> +	V4L2_WHITE_BALANCE_PRESET_NONE		= 0,
> +	V4L2_WHITE_BALANCE_PRESET_INCANDESCENT	= 1,
> +	V4L2_WHITE_BALANCE_PRESET_FLUORESCENT	= 2,
> +	V4L2_WHITE_BALANCE_PRESET_HORIZON	= 3,
> +	V4L2_WHITE_BALANCE_PRESET_DAYLIGHT	= 4,
> +	V4L2_WHITE_BALANCE_PRESET_FLASH		= 5,
> +	V4L2_WHITE_BALANCE_PRESET_CLOUDY	= 6,
> +	V4L2_WHITE_BALANCE_PRESET_SHADE		= 7,
> +};
> +
>   /* FM Modulator class control IDs */
>   #define V4L2_CID_FM_TX_CLASS_BASE		(V4L2_CTRL_CLASS_FM_TX | 0x900)
>   #define V4L2_CID_FM_TX_CLASS			(V4L2_CTRL_CLASS_FM_TX | 1)

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 10/15] V4L: Add camera 3A lock control
  2012-04-17 10:09 ` [PATCH 10/15] V4L: Add camera 3A lock control Sylwester Nawrocki
@ 2012-04-17 16:09   ` Sakari Ailus
  2012-04-18  9:01     ` Sylwester Nawrocki
  0 siblings, 1 reply; 27+ messages in thread
From: Sakari Ailus @ 2012-04-17 16:09 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: linux-media, laurent.pinchart, g.liakhovetski, hdegoede, moinejf,
	m.szyprowski, riverful.kim, sw0312.kim, Kyungmin Park

Hi Sylwester,

On Tue, Apr 17, 2012 at 12:09:51PM +0200, Sylwester Nawrocki wrote:
> The V4L2_CID_3A_LOCK bitmask control allows applications to pause
> or resume the automatic exposure, focus and wite balance adjustments.
> It can be used, for example, to lock the 3A adjustments right before
> a still image is captured, for pre-focus, etc.
> The applications can control each of the algorithms independently,
> through a corresponding control bit, if driver allows that.

How is disabling e.g. focus algorithm different from locking focus?

Regards,

-- 
Sakari Ailus
e-mail: sakari.ailus@iki.fi	jabber/XMPP/Gmail: sailus@retiisi.org.uk

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 04/15] V4L: Add camera white balance preset control
  2012-04-17 13:23   ` Hans de Goede
@ 2012-04-18  8:46     ` Sylwester Nawrocki
  0 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-18  8:46 UTC (permalink / raw)
  To: Hans de Goede
  Cc: linux-media, laurent.pinchart, sakari.ailus, g.liakhovetski,
	moinejf, m.szyprowski, riverful.kim, sw0312.kim, Kyungmin Park

Hi Hans,

On 04/17/2012 03:23 PM, Hans de Goede wrote:
> Hi,
> 
> On 04/17/2012 12:09 PM, Sylwester Nawrocki wrote:
>> Add V4L2_CID_WHITE_BALANCE_PRESET control for camera white balance
>> presets. The following items are defined:
>>
>>   - V4L2_WHITE_BALANCE_NONE,
>>   - V4L2_WHITE_BALANCE_INCANDESCENT,
>>   - V4L2_WHITE_BALANCE_FLUORESCENT,
>>   - V4L2_WHITE_BALANCE_HORIZON,
>>   - V4L2_WHITE_BALANCE_DAYLIGHT,
>>   - V4L2_WHITE_BALANCE_FLASH,
>>   - V4L2_WHITE_BALANCE_CLOUDY,
>>   - V4L2_WHITE_BALANCE_SHADE,
>>
>> This is a manual white balance control, in addition to V4L2_CID_RED_BALANCE,
>> V4L2_CID_BLUE_BALANCE and V4L2_CID_WHITE_BALANCE_TEMPERATURE. It's useful
>> for camera devices running more complex firmware and exposing white balance
>> preset selection in their user register interface.
> 
> Hmm, how is this supposed to work together with the v4l2-ctrls framework?
> The framework has a concept of a master control, which has a manual value,
> and the slave controls will only get unlocked (V4L2_CTRL_FLAG_INACTIVE
> will be cleared) when that master control is set at its manual value, now lets
> say that we've V4L2_CID_AUTO_WHITE_BALANCE as master with
> V4L2_CID_WHITE_BALANCE_PRESET and V4L2_CID_RED_BALANCE and V4L2_CID_BLUE_BALANCE
> slaves. Then when the master control changes from auto to manual all 3 will
> have their inactive flag cleared, but if the preset value !=
> V4L2_WHITE_BALANCE_NONE
> then the red- and blue-balance should have kept their inactive flag. And since
> this
> clearing of the inactive flag is done after v4l2-ctrls.c has called into the
> driver there is no way for the driver to fix this.
> 
> One could work-around this by not specifying the whitebalance control cluster as
> being an auto cluster, and doing all the auto cluster stuff from the driver, but
> that significantly complicates the driver, and we are trying to get away of every
> driver doing this kinda stuff for itself...

I assumed in common cases there will be just pairs of auto/manual controls
(or control groups) used, e.g. V4L2_CID_AUTO_WHITE_BALANCE and 
V4L2_CID_RED_BALANCE/V4L2_CID_BLUE_BALANCE, or V4L2_CID_AUTO_WHITE_BALANCE and
V4L2_CID_WHITE_BALANCE_TEMPERATURE or V4L2_CID_AUTO_WHITE_BALANCE and
V4L2_CID_WHITE_BALANCE_PRESET, etc.

This is really what the control framework support now, i.e. one master cluster
control with single value that swithes whole cluster into manual mode, AFAICS.

I assumed more complicated cases will have to be coded in drivers for now. Or
can be handled my the control framework, if those patterns appear to be often
used and the control framework is enhanced to better support them.

I tried to come up with a solution that could be also used by the pwc driver
and to expose all functionality available there.

> I still believe that the solution I came up with for pwc is better, the auto
> whitebalance control really is a tri state when you add presets whitebalance
> is controlled through one of this 3 options:
> 1) auto
> 2) preset
> 3) manual

2) and 3) will often be exclusive, so we cannot just unlock (clear the 
V4L2_CTRL_FLAG_INACTIVE flag) on them, when the WB menu is switched to value
other than "auto". This would happen when the WB menu and 2), 3) would form 
an auto cluster.

Moreover, we also have V4L2_CID_WHITE_BALANCE_TEMPERATURE as a manual WB control.
I assumed the WB presets are just form of it, with names (labels).

I am a bit concerned that with the menu control we might exclude at API level
a possibility of altering some of the controls simultaneously, e.g. preset
and red/blue balance.

> I know you are worried about having a V4L2_CID_AUTO_WHITE_BALANCE control
> which is not a boolean breaking apps, well the pwc driver is a quite popular
> driver and I've had 0 bug reports about my turning it into a menu...

I wish I could simply change the control type to a menu, but breaking ABI doesn't
sound like an option. I think the patch doing something like the at the core level
would have been rejected right away. So the new menu control sounds better to me,
except that it doesn't make our situation much easier, however it might be what
we wanted in long term.

> Alternatively we could add a new V4L2_CID_WHITE_BALANCE_MENU control and use
> that for drivers which have presets rather then the old
> V4L2_CID_AUTO_WHITE_BALANCE
> to ensure that userspace won't trip over it being a menu all of a sudden, but
> I believe that it is really important to properly reflect the tri-state nature
> of the awb once presets come into play, rather then trying to bolt something

Is it really tri-state ? I think it just an auto (perhaps multiple auto at some 
point?) and multiple manual states. Should we really consider the presets as 
something other than manual control ?

> on top of / to the side of our current bi-state control. And I hope that my above
> example of what sort of troubles using the bolt-on solution will give, clearly
> demonstrates that the bolt-on solution is a bad idea.

If we decided to add a new V4L2_CID_WHITE_BALANCE_MENU control, then we should
probably deprecate V4L2_CID_AUTO_WHITE_BALANCE, as having both would be confusing.
Then the V4L2_CID_AUTO_WHITE_BALANCE would have been removed and maybe after some
time added as an alias for V4L2_CID_WHITE_BALANCE_MENU. Sound terribly painful
though. This all makes me think we might be missing some reliable API version
scheme.

I'm also not very happy with appending a _MENU suffix, indicating the control's
type. 


-- 
Regards,
Sylwester

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 10/15] V4L: Add camera 3A lock control
  2012-04-17 16:09   ` Sakari Ailus
@ 2012-04-18  9:01     ` Sylwester Nawrocki
  2012-04-23  5:47       ` Sakari Ailus
  0 siblings, 1 reply; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-18  9:01 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: linux-media, laurent.pinchart, g.liakhovetski, hdegoede, moinejf,
	m.szyprowski, riverful.kim, sw0312.kim, Kyungmin Park

Hi Sakari,

On 04/17/2012 06:09 PM, Sakari Ailus wrote:
> Hi Sylwester,
> 
> On Tue, Apr 17, 2012 at 12:09:51PM +0200, Sylwester Nawrocki wrote:
>> The V4L2_CID_3A_LOCK bitmask control allows applications to pause
>> or resume the automatic exposure, focus and wite balance adjustments.
>> It can be used, for example, to lock the 3A adjustments right before
>> a still image is captured, for pre-focus, etc.
>> The applications can control each of the algorithms independently,
>> through a corresponding control bit, if driver allows that.
> 
> How is disabling e.g. focus algorithm different from locking focus?

The difference looks quite obvious to me. When some AUTO control is
switched from auto to manual mode there is no guarantee about the
related parameters the device will end up. E.g. lens may be positioned
into default position, rather than kept at current one, exposure might
be set to manual value from before AE was enabled, etc.

I've seen separate registers at the sensor interfaces for AE, AWB
locking/unlocking and for disabling/enabling those algorithms.
With the proposed control applications can be sure that, for example,
exposure is retained when the V4L2_CID_3A_LOCK is set.

Does it answer your question ?

--
Regards,
Sylwester

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 01/15] V4L: Extend V4L2_CID_COLORFX with more image effects
  2012-04-17 11:28     ` Sylwester Nawrocki
@ 2012-04-22 16:00       ` Sylwester Nawrocki
  0 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-22 16:00 UTC (permalink / raw)
  To: linux-media
  Cc: Sylwester Nawrocki, Rémi Denis-Courmont, laurent.pinchart,
	sakari.ailus, g.liakhovetski, hdegoede, moinejf, m.szyprowski,
	riverful.kim, sw0312.kim, Kyungmin Park

On 04/17/2012 01:28 PM, Sylwester Nawrocki wrote:
> On 04/17/2012 12:51 PM, Rémi Denis-Courmont wrote:
>> On Tue, 17 Apr 2012 12:09:42 +0200, Sylwester Nawrocki
>> <s.nawrocki@samsung.com>  wrote:
>>> This patch adds definition of additional color effects:
>>>   - V4L2_COLORFX_AQUA,
>>>   - V4L2_COLORFX_ART_FREEZE,
>>>   - V4L2_COLORFX_SILHOUETTE,
>>>   - V4L2_COLORFX_SOLARIZATION,
>>>   - V4L2_COLORFX_ANTIQUE,
>>
>> There starts to be a lot of different color effects with no obvious way to
>> determine which ones the current device actually suppots. Should this not
>> be a menu control instead?
> 
> Fortunately this has been a menu control, since it was introduced. Only
> the DocBook erroneously defined it as an enum. This patch also fixes that,
> please see the DocBook part.
> 
>>>   - V4L2_COLORFX_ARBITRARY.
>>>
>>> The control's type in the documentation is changed from 'enum' to 'menu'
>>> - V4L2_CID_COLORFX has always been a menu, not an integer type control.
>>>
>>> The V4L2_COLORFX_ARBITRARY option enables custom color effects, which
>> are
>>> impossible or impractical to define as the menu items. For example, the
>>> devices may provide coefficients for Cb and Cr manipulation, which yield
>>> many permutations, e.g. many slightly different color tints. Such
>> devices
>>> are better exporting their own API for precise control of non-standard
>>> color effects.
>>
>> I don't understand why you need a number for this, if it's going to use
>> another control anyway... ?
> 
> In my use case, the hardware has 3 registers: one of them selects the colour
> effect and two others determine Cr, Cb coefficients (probably I could use
> V4L2_CID_RED_BALANCE, V4L2_CID_BLUE_BALANCE for that, but so far these are
> just private controls).
> 
> If I would have removed the V4L2_COLORFX_ARBITRARY item, another control
> would have to be added (let's say boolean V4L2_PRIV_IMG_EFFECT). Just to
> enable the "arbitrary" effect.
> 
> Then, to enable the arbitrary effect V4L2_CID_COLORFX would have to be set
> to V4L2_COLORFX_NONE, and V4L2_PRIV_IMG_EFFECT to true.
> 
> The CB, CR coefficients are meaningful only when the arbitrary effect is
> selected. So having another option in the menu, which drivers can just mask
> if they don't support it, appeared better to me.
> 
> It's a bit similar to gain/autogain scenario, where gain is active only when
> autogain is off.
> Maybe I should just add another private control (V4L2_PRIV_IMG_EFFECT) and
> remove V4L2_COLORFX_ARBITRARY item.

Instead of an imprecise V4L2_COLORFX_ARBITRARY, I'm considering adding 
V4L2_COLORFX_CHROMA_BALANCE item and document that it should be used together 
with V4L2_CID_RED_BALANCE and V4L2_CID_BLUE_BALANCE controls. Would something 
like this be acceptable ? I'd like to avoid (many) private controls if possible.

---
Regards,
Sylwester

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 10/15] V4L: Add camera 3A lock control
  2012-04-18  9:01     ` Sylwester Nawrocki
@ 2012-04-23  5:47       ` Sakari Ailus
  2012-04-24 20:12         ` Sylwester Nawrocki
  0 siblings, 1 reply; 27+ messages in thread
From: Sakari Ailus @ 2012-04-23  5:47 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: linux-media, laurent.pinchart, g.liakhovetski, hdegoede, moinejf,
	m.szyprowski, riverful.kim, sw0312.kim, Kyungmin Park

Hi Sylwester,

Sylwester Nawrocki wrote:
> Hi Sakari,
>
> On 04/17/2012 06:09 PM, Sakari Ailus wrote:
>> Hi Sylwester,
>>
>> On Tue, Apr 17, 2012 at 12:09:51PM +0200, Sylwester Nawrocki wrote:
>>> The V4L2_CID_3A_LOCK bitmask control allows applications to pause
>>> or resume the automatic exposure, focus and wite balance adjustments.
>>> It can be used, for example, to lock the 3A adjustments right before
>>> a still image is captured, for pre-focus, etc.
>>> The applications can control each of the algorithms independently,
>>> through a corresponding control bit, if driver allows that.
>>
>> How is disabling e.g. focus algorithm different from locking focus?
>
> The difference looks quite obvious to me. When some AUTO control is
> switched from auto to manual mode there is no guarantee about the
> related parameters the device will end up. E.g. lens may be positioned
> into default position, rather than kept at current one, exposure might
> be set to manual value from before AE was enabled, etc.
>
> I've seen separate registers at the sensor interfaces for AE, AWB
> locking/unlocking and for disabling/enabling those algorithms.
> With the proposed control applications can be sure that, for example,
> exposure is retained when the V4L2_CID_3A_LOCK is set.
>
> Does it answer your question ?

Yes, it does.

I was thinking how does the situation really differ from disabling the
corresponding automatic algorithm. There may be subtle differences in
practice albeit in principle the two are no different. And if some of the
sensors implement it as lock, then I guess it gives us few options for the
user space interface.

-- 
Sakari Ailus
sakari.ailus@iki.fi

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 10/15] V4L: Add camera 3A lock control
  2012-04-23  5:47       ` Sakari Ailus
@ 2012-04-24 20:12         ` Sylwester Nawrocki
  2012-04-24 20:59           ` Sakari Ailus
  0 siblings, 1 reply; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-24 20:12 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Sylwester Nawrocki, linux-media, laurent.pinchart,
	g.liakhovetski, hdegoede, moinejf, m.szyprowski, riverful.kim,
	sw0312.kim, Kyungmin Park

Moikka Sakari,

On 04/23/2012 07:47 AM, Sakari Ailus wrote:
> Sylwester Nawrocki wrote:
>> On 04/17/2012 06:09 PM, Sakari Ailus wrote:
>>> On Tue, Apr 17, 2012 at 12:09:51PM +0200, Sylwester Nawrocki wrote:
>>>> The V4L2_CID_3A_LOCK bitmask control allows applications to pause
>>>> or resume the automatic exposure, focus and wite balance adjustments.
>>>> It can be used, for example, to lock the 3A adjustments right before
>>>> a still image is captured, for pre-focus, etc.
>>>> The applications can control each of the algorithms independently,
>>>> through a corresponding control bit, if driver allows that.
>>>
>>> How is disabling e.g. focus algorithm different from locking focus?
>>
>> The difference looks quite obvious to me. When some AUTO control is
>> switched from auto to manual mode there is no guarantee about the
>> related parameters the device will end up. E.g. lens may be positioned
>> into default position, rather than kept at current one, exposure might
>> be set to manual value from before AE was enabled, etc.
>>
>> I've seen separate registers at the sensor interfaces for AE, AWB
>> locking/unlocking and for disabling/enabling those algorithms.
>> With the proposed control applications can be sure that, for example,
>> exposure is retained when the V4L2_CID_3A_LOCK is set.
>>
>> Does it answer your question ?
> 
> Yes, it does.
> 
> I was thinking how does the situation really differ from disabling the
> corresponding automatic algorithm. There may be subtle differences in
> practice albeit in principle the two are no different. And if some of the
> sensors implement it as lock, then I guess it gives us few options for the
> user space interface.

Can you anticipate any any possible issues such diversity might bring to
applications ? I imagine such control can be quite useful for snapshot,
and with current control API design and the drivers' behaviour applications 
cannot be sure what settings a device ends up with after switching from
"auto" to "manual" - last auto settings or the manual values. Usually its
just the previous manual values.

Such a bitmask control looks quite useful to me. Moreover, at the moment 
there is no control that would provide similar functionality for auto focus.
The bitmask control allows to easily control auto exposure, wb and focus
atomically. However that's not a big deal, since this could be well achieved
with the extended control API.

Although V4L2_CID_3A_LOCK might be hard to implement in driver which use
the control framework, since it would depend on multiple other controls.
But this could be worked around by updating proper control current values
and sending a control event from driver manually, unless you want to cluster
almost all controls.

--

Regards,
Sylwester

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 10/15] V4L: Add camera 3A lock control
  2012-04-24 20:12         ` Sylwester Nawrocki
@ 2012-04-24 20:59           ` Sakari Ailus
  2012-04-29  9:27             ` Sylwester Nawrocki
  0 siblings, 1 reply; 27+ messages in thread
From: Sakari Ailus @ 2012-04-24 20:59 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: Sylwester Nawrocki, linux-media, laurent.pinchart,
	g.liakhovetski, hdegoede, moinejf, m.szyprowski, riverful.kim,
	sw0312.kim, Kyungmin Park

Dzien dobry Sylwester,

(I hope it's not too wrong time of the day for that! ;))

Sylwester Nawrocki wrote:
> Moikka Sakari,
>
> On 04/23/2012 07:47 AM, Sakari Ailus wrote:
>> Sylwester Nawrocki wrote:
>>> On 04/17/2012 06:09 PM, Sakari Ailus wrote:
>>>> On Tue, Apr 17, 2012 at 12:09:51PM +0200, Sylwester Nawrocki wrote:
>>>>> The V4L2_CID_3A_LOCK bitmask control allows applications to pause
>>>>> or resume the automatic exposure, focus and wite balance adjustments.
>>>>> It can be used, for example, to lock the 3A adjustments right before
>>>>> a still image is captured, for pre-focus, etc.
>>>>> The applications can control each of the algorithms independently,
>>>>> through a corresponding control bit, if driver allows that.
>>>>
>>>> How is disabling e.g. focus algorithm different from locking focus?
>>>
>>> The difference looks quite obvious to me. When some AUTO control is
>>> switched from auto to manual mode there is no guarantee about the
>>> related parameters the device will end up. E.g. lens may be positioned
>>> into default position, rather than kept at current one, exposure might
>>> be set to manual value from before AE was enabled, etc.
>>>
>>> I've seen separate registers at the sensor interfaces for AE, AWB
>>> locking/unlocking and for disabling/enabling those algorithms.
>>> With the proposed control applications can be sure that, for example,
>>> exposure is retained when the V4L2_CID_3A_LOCK is set.
>>>
>>> Does it answer your question ?
>>
>> Yes, it does.
>>
>> I was thinking how does the situation really differ from disabling the
>> corresponding automatic algorithm. There may be subtle differences in
>> practice albeit in principle the two are no different. And if some of the
>> sensors implement it as lock, then I guess it gives us few options for the
>> user space interface.
>
> Can you anticipate any any possible issues such diversity might bring to
> applications ? I imagine such control can be quite useful for snapshot,
> and with current control API design and the drivers' behaviour applications
> cannot be sure what settings a device ends up with after switching from
> "auto" to "manual" - last auto settings or the manual values. Usually its
> just the previous manual values.

On software controlled digital cameras, depending on what the manual 
configuration actually means, you either get the same than by locking 
the automatic control or the previous manual configuration. If the means 
for manual configuration are the same than what the automatic algorithm 
uses then it's the first case. However, I have a feeling that such low 
level controls might often not work the best for manual control: for 
white balance users seldom wish to fiddle with SRGB matrix or gamma 
tables directly. Colour balance might just do mostly the same and be 
more convenient, with the automatic algorithm still doing some work to 
configure the underlying low-level configuration.

Perhaps it would make sense to suggest that the control algorithm locks 
should be implemented even in cases where the lock would mean exactly 
the same than just disabling the algorithm. What do you think?

Shouldn't the lock be related to contiguous focus only btw.? Regular 
autofocus is typically a one-time operation, the lens ending up on a 
position where the AF algorithm left it.

> Such a bitmask control looks quite useful to me. Moreover, at the moment
> there is no control that would provide similar functionality for auto focus.
> The bitmask control allows to easily control auto exposure, wb and focus
> atomically. However that's not a big deal, since this could be well achieved
> with the extended control API.
>
> Although V4L2_CID_3A_LOCK might be hard to implement in driver which use
> the control framework, since it would depend on multiple other controls.
> But this could be worked around by updating proper control current values
> and sending a control event from driver manually, unless you want to cluster
> almost all controls.

Cheers,

-- 
Sakari Ailus
sakari.ailus@iki.fi

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH 10/15] V4L: Add camera 3A lock control
  2012-04-24 20:59           ` Sakari Ailus
@ 2012-04-29  9:27             ` Sylwester Nawrocki
  0 siblings, 0 replies; 27+ messages in thread
From: Sylwester Nawrocki @ 2012-04-29  9:27 UTC (permalink / raw)
  To: Sakari Ailus
  Cc: Sylwester Nawrocki, linux-media, laurent.pinchart,
	g.liakhovetski, hdegoede, moinejf, m.szyprowski, riverful.kim,
	sw0312.kim, Kyungmin Park

Hi Sakari,

On 04/24/2012 10:59 PM, Sakari Ailus wrote:
> Dzien dobry Sylwester,
> 
> (I hope it's not too wrong time of the day for that! ;))

No, it's never too wrong;)

> Sylwester Nawrocki wrote:
>> On 04/23/2012 07:47 AM, Sakari Ailus wrote:
>>> Sylwester Nawrocki wrote:
>>>> On 04/17/2012 06:09 PM, Sakari Ailus wrote:
>>>>> On Tue, Apr 17, 2012 at 12:09:51PM +0200, Sylwester Nawrocki wrote:
...
>>> I was thinking how does the situation really differ from disabling the
>>> corresponding automatic algorithm. There may be subtle differences in
>>> practice albeit in principle the two are no different. And if some of 
>>> the
>>> sensors implement it as lock, then I guess it gives us few options 
>>> for the
>>> user space interface.
>>
>> Can you anticipate any any possible issues such diversity might bring to
>> applications ? I imagine such control can be quite useful for snapshot,
>> and with current control API design and the drivers' behaviour 
>> applications
>> cannot be sure what settings a device ends up with after switching from
>> "auto" to "manual" - last auto settings or the manual values. Usually its
>> just the previous manual values.
> 
> On software controlled digital cameras, depending on what the manual 
> configuration actually means, you either get the same than by locking 
> the automatic control or the previous manual configuration. If the means 
> for manual configuration are the same than what the automatic algorithm 
> uses then it's the first case. However, I have a feeling that such low 
> level controls might often not work the best for manual control: for 
> white balance users seldom wish to fiddle with SRGB matrix or gamma 
> tables directly. Colour balance might just do mostly the same and be 
> more convenient, with the automatic algorithm still doing some work to 
> configure the underlying low-level configuration.

I was thinking more along the lines of currently available V4L2 
controls. And with cameras with I2C control interface there is often
a device specific user interface of which characteristics are slightly 
different that what we would have implemented directly in software in 
user space. 

> Perhaps it would make sense to suggest that the control algorithm locks 
> should be implemented even in cases where the lock would mean exactly 
> the same than just disabling the algorithm. What do you think?

IMHO a driver should expose the control only if hardware supports 
locking. Once we have clear semantics for the lock control, it should
be up to the driver's author to decide whether such functionality 
should be exposed or not. I believe the locking and disabling/enabling 
automatic settings will differ in most cases, there may be different
latencies involved, etc. 

Also I think the lock control should have top priority, .e.g when
the user sets V4L2_CID_AUTO_FOCUS_START control nothing should 
happen, unless V4L2_LOCK_FOCUS is set to 0. What do you think ?

BTW, I've changed names of the individual lock bits an removed 
"_3A" prefix from them. It seems to look better that way:

#define V4L2_CID_3A_LOCK	(V4L2_CID_CAMERA_CLASS_BASE+27)
#define V4L2_LOCK_EXPOSURE	(1 << 0)
#define V4L2_LOCK_WHITE_BALANCE	(1 << 1)
#define V4L2_LOCK_FOCUS		(1 << 2)

Or must we abide the rule that individual option names are created 
by only removing the "_CID" part from the control name and appending
the option's name ?

> Shouldn't the lock be related to contiguous focus only btw.? Regular 
> autofocus is typically a one-time operation, the lens ending up on a 
> position where the AF algorithm left it.

Perhaps, it would make sense mostly for continuous auto focus. 
However, I'm inclined to not limit it to continuous auto focus only. 
I think regardless of the focus mode the lock should freeze focusing,
so still image capture is not disturbed.


--

Regards,
Sylwester

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2012-04-29  9:27 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-17 10:09 [PATCH 00/15] V4L camera control enhancements Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 01/15] V4L: Extend V4L2_CID_COLORFX with more image effects Sylwester Nawrocki
2012-04-17 10:51   ` Rémi Denis-Courmont
2012-04-17 11:28     ` Sylwester Nawrocki
2012-04-22 16:00       ` Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 02/15] V4L: Add helper function for standard integer menu controls Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 03/15] V4L: Add camera exposure bias control Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 04/15] V4L: Add camera white balance preset control Sylwester Nawrocki
2012-04-17 13:23   ` Hans de Goede
2012-04-18  8:46     ` Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 05/15] V4L: Add camera wide dynamic range control Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 06/15] V4L: Add camera image stabilization control Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 07/15] V4L: Add camera ISO sensitivity controls Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 08/15] V4L: Add camera exposure metering control Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 09/15] V4L: Add camera scene mode control Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 10/15] V4L: Add camera 3A lock control Sylwester Nawrocki
2012-04-17 16:09   ` Sakari Ailus
2012-04-18  9:01     ` Sylwester Nawrocki
2012-04-23  5:47       ` Sakari Ailus
2012-04-24 20:12         ` Sylwester Nawrocki
2012-04-24 20:59           ` Sakari Ailus
2012-04-29  9:27             ` Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 11/15] V4L: Add auto focus targets to the selections API Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 12/15] V4L: Add auto focus targets to the subdev " Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 13/15] V4L: Add camera auto focus controls Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 14/15] V4L: Add S5C73M3 sensor sub-device driver Sylwester Nawrocki
2012-04-17 10:09 ` [PATCH 15/15] vivi: Add controls Sylwester Nawrocki

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.