All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH/RFC v3 00/14] V4L camera control enhancements
@ 2012-04-27 14:23 Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 01/14] V4L: Add helper function for standard integer menu controls Sylwester Nawrocki
                   ` (15 more replies)
  0 siblings, 16 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, m.szyprowski, riverful.kim, sw0312.kim,
	s.nawrocki

Here is one more update of the camera class controls change set.

The changes since v2 are:
 - V4L2_CID_WHITE_BALANCE_PRESET replaced with V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE
   according to suggestions from Hans de Goede;
 - added Flurescent H white balance preset;
 - V4L2_CID_IMAGE_STABILIZATION and V4L2_CID_WIDE_DYNAMIC_RANGE controls type 
   changed from boolean to menu, to make any further extensions of these 
   controls easier;
   I'm just not 100% sure if V4L2_WIDE_DYNAMIC_RANGE_ENABLED and
   V4L2_IMAGE_STABILIZATION_ENABLED are good names for cases where the camera
   doesn't support wide dynamic range or image stabilization technique
   selection and only allows to enable or disable those algorithms;	 
 - V4L2_CID_ISO_SENSITIVITY_AUTO control type changed from boolean to menu in
   order to support ISO presets; currently enum v4l2_iso_sensitivity_auto_type
   does not contain any presets though;
 - V4L2_CID_COLORFX patch removed from this series;
 - updated vivi and s5c73m3 driver patches.

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.

The patches are also available in a git repository at:
http://git.infradead.org/users/kmpark/linux-samsung/shortlog/refs/heads/v4l-controls-s5c73m3


Thanks,
Sylwester


Sylwester Nawrocki (14):
  V4L: Add helper function for standard integer menu controls
  V4L: Add camera exposure bias control
  V4L: Add an extended camera white balance 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       |  501 +++++++-
 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        |  705 +++++++++++
 drivers/media/video/s5c73m3/s5c73m3-spi.c          |  126 ++
 drivers/media/video/s5c73m3/s5c73m3.c              | 1243 ++++++++++++++++++++
 drivers/media/video/s5c73m3/s5c73m3.h              |  442 +++++++
 drivers/media/video/v4l2-ctrls.c                   |  133 ++-
 drivers/media/video/vivi.c                         |  111 +-
 include/linux/v4l2-subdev.h                        |    4 +
 include/linux/videodev2.h                          |   92 ++
 include/media/s5c73m3.h                            |   62 +
 include/media/v4l2-ctrls.h                         |   17 +
 19 files changed, 3536 insertions(+), 8 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] 31+ messages in thread

* [PATCH/RFC v3 01/14] V4L: Add helper function for standard integer menu controls
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-30 15:20   ` Hans Verkuil
  2012-04-27 14:23 ` [PATCH/RFC v3 02/14] V4L: Add camera exposure bias control Sylwester Nawrocki
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, 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 c93a979..e0725b5 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -1517,6 +1517,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 8920f82..15116d2 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -347,6 +347,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] 31+ messages in thread

* [PATCH/RFC v3 02/14] V4L: Add camera exposure bias control
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 01/14] V4L: Add helper function for standard integer menu controls Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 03/14] V4L: Add an extended camera white balance control Sylwester Nawrocki
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, 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 5038a3a..56a53a8 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -2775,6 +2775,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 e0725b5..1d7091f 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -597,6 +597,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! */
@@ -739,6 +740,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 5a09ac3..da60cbb 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1693,6 +1693,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] 31+ messages in thread

* [PATCH/RFC v3 03/14] V4L: Add an extended camera white balance control
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 01/14] V4L: Add helper function for standard integer menu controls Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 02/14] V4L: Add camera exposure bias control Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-27 14:30   ` Hans de Goede
  2012-04-27 14:23 ` [PATCH/RFC v3 04/14] V4L: Add camera wide dynamic range control Sylwester Nawrocki
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, m.szyprowski, riverful.kim, sw0312.kim,
	s.nawrocki, Kyungmin Park

This patch adds V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE control which is
an extended version of the V4L2_CID_AUTO_WHITE_BALANCE control,
including white balance presets. The following presets are defined:

 - V4L2_WHITE_BALANCE_INCANDESCENT,
 - V4L2_WHITE_BALANCE_FLUORESCENT,
 - V4L2_WHITE_BALANCE_FLUORESCENT_H,
 - V4L2_WHITE_BALANCE_HORIZON,
 - V4L2_WHITE_BALANCE_DAYLIGHT,
 - V4L2_WHITE_BALANCE_FLASH,
 - V4L2_WHITE_BALANCE_CLOUDY,
 - V4L2_WHITE_BALANCE_SHADE.

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 |   70 ++++++++++++++++++++++++++
 drivers/media/video/v4l2-ctrls.c             |   17 +++++++
 include/linux/videodev2.h                    |   14 ++++++
 3 files changed, 101 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 56a53a8..b671a70 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -2948,6 +2948,76 @@ 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-auto-n-preset-white-balance-type">
+	    <entry spanname="id"><constant>V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE</constant>&nbsp;</entry>
+	    <entry>enum&nbsp;v4l2_auto_n_preset_white_balance_type</entry>
+	  </row><row><entry spanname="descr">Sets white balance to automatic,
+manual or a preset. The presets determine color temperature of the light as
+a hint to the camera for white balance adjustments resulting in most accurate
+color representation. 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_MANUAL</constant>&nbsp;</entry>
+		  <entry>Manual white balance.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_AUTO</constant>&nbsp;</entry>
+		  <entry>Automatic white balance adjustments.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_INCANDESCENT</constant>&nbsp;</entry>
+		  <entry>White balance setting 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_FLUORESCENT</constant>&nbsp;</entry>
+		  <entry>White balance preset for fluorescent lighting.
+It corresponds approximately to 4000...5000 K color temperature.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_FLUORESCENT_H</constant>&nbsp;</entry>
+		  <entry>With this setting the camera will compensate for
+fluorescent H lighting.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_HORIZON</constant>&nbsp;</entry>
+		  <entry>White balance setting for horizon daylight.
+It corresponds approximately to 5000 K color temperature.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_DAYLIGHT</constant>&nbsp;</entry>
+		  <entry>White balance preset for daylight (with clear sky).
+It corresponds approximately to 5000...6500 K color temperature.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_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_CLOUDY</constant>&nbsp;</entry>
+		  <entry>White balance preset for moderately overcast sky.
+This option corresponds approximately to 6500...8000 K color temperature
+range.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WHITE_BALANCE_SHADE</constant>&nbsp;</entry>
+		  <entry>White balance preset 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 1d7091f..02fa9b0 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -243,6 +243,19 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		"Vivid",
 		NULL
 	};
+	static const char * const auto_n_preset_white_balance[] = {
+		"Manual",
+		"Auto",
+		"Incandescent",
+		"Fluorescent",
+		"Fluorescent H",
+		"Horizon",
+		"Daylight",
+		"Flash",
+		"Cloudy",
+		"Shade",
+		NULL,
+	};
 	static const char * const tune_preemphasis[] = {
 		"No Preemphasis",
 		"50 Microseconds",
@@ -412,6 +425,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		return camera_exposure_auto;
 	case V4L2_CID_COLORFX:
 		return colorfx;
+	case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
+		return auto_n_preset_white_balance;
 	case V4L2_CID_TUNE_PREEMPHASIS:
 		return tune_preemphasis;
 	case V4L2_CID_FLASH_LED_MODE:
@@ -598,6 +613,7 @@ 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_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & Preset";
 
 	/* FM Radio Modulator control */
 	/* Keep the order of the 'case's the same as in videodev2.h! */
@@ -721,6 +737,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_AUTO_N_PRESET_WHITE_BALANCE:
 	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 da60cbb..08891e6 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1695,6 +1695,20 @@ enum  v4l2_exposure_auto_type {
 
 #define V4L2_CID_AUTO_EXPOSURE_BIAS		(V4L2_CID_CAMERA_CLASS_BASE+19)
 
+#define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE	(V4L2_CID_CAMERA_CLASS_BASE+20)
+enum v4l2_auto_n_preset_white_balance_type {
+	V4L2_WHITE_BALANCE_MANUAL		= 0,
+	V4L2_WHITE_BALANCE_AUTO			= 1,
+	V4L2_WHITE_BALANCE_INCANDESCENT		= 2,
+	V4L2_WHITE_BALANCE_FLUORESCENT		= 3,
+	V4L2_WHITE_BALANCE_FLUORESCENT_H	= 4,
+	V4L2_WHITE_BALANCE_HORIZON		= 5,
+	V4L2_WHITE_BALANCE_DAYLIGHT		= 6,
+	V4L2_WHITE_BALANCE_FLASH		= 7,
+	V4L2_WHITE_BALANCE_CLOUDY		= 8,
+	V4L2_WHITE_BALANCE_SHADE		= 9,
+};
+
 /* 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] 31+ messages in thread

* [PATCH/RFC v3 04/14] V4L: Add camera wide dynamic range control
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (2 preceding siblings ...)
  2012-04-27 14:23 ` [PATCH/RFC v3 03/14] V4L: Add an extended camera white balance control Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-30 15:50   ` Hans Verkuil
  2012-04-27 14:23 ` [PATCH/RFC v3 05/14] V4L: Add camera image stabilization control Sylwester Nawrocki
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, m.szyprowski, riverful.kim, sw0312.kim,
	s.nawrocki, Kyungmin Park

Add V4L2_CID_WIDE_DYNAMIC_RANGE camera class control for camera wide
dynamic range (WDR, HDR) feature. This control has now only menu entries
for enabling and disabling WDR. It can be extended when the wide dynamic
range technique selection is needed.

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 |   28 ++++++++++++++++++++++++++
 drivers/media/video/v4l2-ctrls.c             |    9 +++++++++
 include/linux/videodev2.h                    |    6 ++++++
 3 files changed, 43 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index b671a70..487b7b5 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3018,6 +3018,34 @@ sky. It corresponds approximately to 9000...10000 K color temperature.
 	  </row>
 	  <row><entry></entry></row>
 
+	  <row id="v4l2-wide-dynamic-range-type">
+	    <entry spanname="id"><constant>V4L2_CID_WIDE_DYNAMIC_RANGE</constant></entry>
+	    <entry>enum&nbsp;v4l2_wide_dynamic_range_type</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 with different exposure
+times.</entry>
+	  </row>
+	  <row>
+	    <entrytbl spanname="descr" cols="2">
+	      <tbody valign="top">
+		<row>
+		  <entry><constant>V4L2_WIDE_DYNAMIC_RANGE_DISABLED</constant></entry>
+		  <entry>Wide dynamic range is disabled.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_WIDE_DYNAMIC_RANGE_ENABLED</constant></entry>
+		  <entry>Wide dynamic range is enabled.</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 02fa9b0..ad2f035 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -256,6 +256,11 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		"Shade",
 		NULL,
 	};
+	static const char * const camera_wide_dynamic_range[] = {
+		"Disabled",
+		"Enabled",
+		NULL
+	};
 	static const char * const tune_preemphasis[] = {
 		"No Preemphasis",
 		"50 Microseconds",
@@ -427,6 +432,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		return colorfx;
 	case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
 		return auto_n_preset_white_balance;
+	case V4L2_CID_WIDE_DYNAMIC_RANGE:
+		return camera_wide_dynamic_range;
 	case V4L2_CID_TUNE_PREEMPHASIS:
 		return tune_preemphasis;
 	case V4L2_CID_FLASH_LED_MODE:
@@ -614,6 +621,7 @@ 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_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & 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! */
@@ -751,6 +759,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_WIDE_DYNAMIC_RANGE:
 		*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 08891e6..3ca9b10 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1709,6 +1709,12 @@ enum v4l2_auto_n_preset_white_balance_type {
 	V4L2_WHITE_BALANCE_SHADE		= 9,
 };
 
+#define V4L2_CID_WIDE_DYNAMIC_RANGE		(V4L2_CID_CAMERA_CLASS_BASE+21)
+enum v4l2_wide_dynamic_range_type {
+	V4L2_WIDE_DYNAMIC_RANGE_DISABLED	= 0,
+	V4L2_WIDE_DYNAMIC_RANGE_ENABLED		= 1,
+};
+
 /* 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] 31+ messages in thread

* [PATCH/RFC v3 05/14] V4L: Add camera image stabilization control
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (3 preceding siblings ...)
  2012-04-27 14:23 ` [PATCH/RFC v3 04/14] V4L: Add camera wide dynamic range control Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 06/14] V4L: Add camera ISO sensitivity controls Sylwester Nawrocki
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, 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. It can be extended with new menu items if the image
stabilization technique selection is needed.

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 |   23 +++++++++++++++++++++++
 drivers/media/video/v4l2-ctrls.c             |    9 +++++++++
 include/linux/videodev2.h                    |    5 +++++
 3 files changed, 37 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 487b7b5..ac27444 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3046,6 +3046,29 @@ times.</entry>
 	  </row>
 	  <row><entry></entry></row>
 
+	  <row id="v4l2-image-stabilization-type">
+	    <entry spanname="id"><constant>V4L2_CID_IMAGE_STABILIZATION</constant></entry>
+	    <entry>enum&nbsp;v4l2_image_stabilization_type</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Enables or disables image stabilization.</entry>
+	  </row>
+	  <row>
+	    <entrytbl spanname="descr" cols="2">
+	      <tbody valign="top">
+		<row>
+		  <entry><constant>V4L2_IMAGE_STABILIZATION_DISABLED</constant></entry>
+		  <entry>Image stabilization is disabled.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_IMAGE_STABILIZATION_ENABLED</constant></entry>
+		  <entry>Image stabilization is enabled.</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 ad2f035..305a203 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -261,6 +261,11 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		"Enabled",
 		NULL
 	};
+	static const char * const camera_image_stabilization[] = {
+		"Disabled",
+		"Enabled",
+		NULL
+	};
 	static const char * const tune_preemphasis[] = {
 		"No Preemphasis",
 		"50 Microseconds",
@@ -434,6 +439,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		return auto_n_preset_white_balance;
 	case V4L2_CID_WIDE_DYNAMIC_RANGE:
 		return camera_wide_dynamic_range;
+	case V4L2_CID_IMAGE_STABILIZATION:
+		return camera_image_stabilization;
 	case V4L2_CID_TUNE_PREEMPHASIS:
 		return tune_preemphasis;
 	case V4L2_CID_FLASH_LED_MODE:
@@ -622,6 +629,7 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_AUTO_EXPOSURE_BIAS:	return "Auto Exposure, Bias";
 	case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & 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! */
@@ -760,6 +768,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_WIDE_DYNAMIC_RANGE:
+	case V4L2_CID_IMAGE_STABILIZATION:
 		*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 3ca9b10..62d1d66 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1714,6 +1714,11 @@ enum v4l2_wide_dynamic_range_type {
 	V4L2_WIDE_DYNAMIC_RANGE_DISABLED	= 0,
 	V4L2_WIDE_DYNAMIC_RANGE_ENABLED		= 1,
 };
+#define V4L2_CID_IMAGE_STABILIZATION		(V4L2_CID_CAMERA_CLASS_BASE+22)
+enum v4l2_image_stabilization_type {
+	V4L2_IMAGE_STABILIZATION_DISABLED	= 0,
+	V4L2_IMAGE_STABILIZATION_ENABLED	= 1,
+};
 
 /* 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] 31+ messages in thread

* [PATCH/RFC v3 06/14] V4L: Add camera ISO sensitivity controls
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (4 preceding siblings ...)
  2012-04-27 14:23 ` [PATCH/RFC v3 05/14] V4L: Add camera image stabilization control Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 07/14] V4L: Add camera exposure metering control Sylwester Nawrocki
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, 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 |   38 ++++++++++++++++++++++++++
 drivers/media/video/v4l2-ctrls.c             |   10 +++++++
 include/linux/videodev2.h                    |    7 +++++
 4 files changed, 66 insertions(+)

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 ac27444..557daae 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3069,6 +3069,44 @@ times.</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. The effect of setting
+this control while the <constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>
+control is set to a value other than <constant>V4L2_CID_ISO_SENSITIVITY_MANUAL
+</constant> is undefined, drivers should ignore such requests.</entry>
+	  </row>
+	  <row><entry></entry></row>
+
+	  <row id="v4l2-iso-sensitivity-auto-type">
+	    <entry spanname="id"><constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>&nbsp;</entry>
+	    <entry>enum&nbsp;v4l2_iso_sensitivity_type</entry>
+	  </row><row><entry spanname="descr">Enables or disables automatic ISO
+sensitivity adjustments.</entry>
+	  </row>
+	  <row>
+	    <entrytbl spanname="descr" cols="2">
+	      <tbody valign="top">
+		<row>
+		  <entry><constant>V4L2_CID_ISO_SENSITIVITY_MANUAL</constant>&nbsp;</entry>
+		  <entry>Manual ISO sensitivity.</entry>
+		</row>
+		<row>
+		  <entry><constant>V4L2_CID_ISO_SENSITIVITY_AUTO</constant>&nbsp;</entry>
+		  <entry>Automatic ISO sensititivity adjustments.</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 305a203..3d8af91 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -264,6 +264,10 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 	static const char * const camera_image_stabilization[] = {
 		"Disabled",
 		"Enabled",
+	};
+	static const char * const camera_iso_sensitivity_auto[] = {
+		"Manual",
+		"Auto",
 		NULL
 	};
 	static const char * const tune_preemphasis[] = {
@@ -441,6 +445,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		return camera_wide_dynamic_range;
 	case V4L2_CID_IMAGE_STABILIZATION:
 		return camera_image_stabilization;
+	case V4L2_CID_ISO_SENSITIVITY_AUTO:
+		return camera_iso_sensitivity_auto;
 	case V4L2_CID_TUNE_PREEMPHASIS:
 		return tune_preemphasis;
 	case V4L2_CID_FLASH_LED_MODE:
@@ -630,6 +636,8 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & 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! */
@@ -769,12 +777,14 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
 	case V4L2_CID_WIDE_DYNAMIC_RANGE:
 	case V4L2_CID_IMAGE_STABILIZATION:
+	case V4L2_CID_ISO_SENSITIVITY_AUTO:
 		*type = V4L2_CTRL_TYPE_MENU;
 		break;
 	case V4L2_CID_RDS_TX_PS_NAME:
 	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 62d1d66..12cc16d 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1720,6 +1720,13 @@ enum v4l2_image_stabilization_type {
 	V4L2_IMAGE_STABILIZATION_ENABLED	= 1,
 };
 
+#define V4L2_CID_ISO_SENSITIVITY		(V4L2_CID_CAMERA_CLASS_BASE+23)
+#define V4L2_CID_ISO_SENSITIVITY_AUTO		(V4L2_CID_CAMERA_CLASS_BASE+24)
+enum v4l2_iso_sensitivity_auto_type {
+	V4L2_ISO_SENSITIVITY_MANUAL		= 0,
+	V4L2_ISO_SENSITIVITY_AUTO		= 1,
+};
+
 /* 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] 31+ messages in thread

* [PATCH/RFC v3 07/14] V4L: Add camera exposure metering control
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (5 preceding siblings ...)
  2012-04-27 14:23 ` [PATCH/RFC v3 06/14] V4L: Add camera ISO sensitivity controls Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 08/14] V4L: Add camera scene mode control Sylwester Nawrocki
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, 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 557daae..8f4fdf8 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -2790,6 +2790,35 @@ exposure time and/or aperture.</para></entry>
 	  </row>
 	  <row><entry></entry></row>
 
+	  <row id="v4l2-exposure-metering-mode">
+	    <entry spanname="id"><constant>V4L2_CID_EXPOSURE_METERING</constant>&nbsp;</entry>
+	    <entry>enum&nbsp;v4l2_exposure_metering_type</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 3d8af91..dcf6b2b 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",
@@ -437,6 +443,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_AUTO_N_PRESET_WHITE_BALANCE:
@@ -638,6 +650,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! */
@@ -778,6 +791,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_WIDE_DYNAMIC_RANGE:
 	case V4L2_CID_IMAGE_STABILIZATION:
 	case V4L2_CID_ISO_SENSITIVITY_AUTO:
+	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 12cc16d..a8588fc 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1727,6 +1727,13 @@ enum v4l2_iso_sensitivity_auto_type {
 	V4L2_ISO_SENSITIVITY_AUTO		= 1,
 };
 
+#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] 31+ messages in thread

* [PATCH/RFC v3 08/14] V4L: Add camera scene mode control
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (6 preceding siblings ...)
  2012-04-27 14:23 ` [PATCH/RFC v3 07/14] V4L: Add camera exposure metering control Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 09/14] V4L: Add camera 3A lock control Sylwester Nawrocki
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, 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             |   21 +++++
 include/linux/videodev2.h                    |   18 ++++
 3 files changed, 156 insertions(+)

diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
index 8f4fdf8..bf481d4 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3136,6 +3136,123 @@ sensitivity adjustments.</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 dcf6b2b..8b48893 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -276,6 +276,23 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		"Auto",
 		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 Microseconds",
@@ -459,6 +476,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
 		return camera_image_stabilization;
 	case V4L2_CID_ISO_SENSITIVITY_AUTO:
 		return camera_iso_sensitivity_auto;
+	case V4L2_CID_SCENE_MODE:
+		return scene_mode;
 	case V4L2_CID_TUNE_PREEMPHASIS:
 		return tune_preemphasis;
 	case V4L2_CID_FLASH_LED_MODE:
@@ -651,6 +670,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! */
@@ -792,6 +812,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_IMAGE_STABILIZATION:
 	case V4L2_CID_ISO_SENSITIVITY_AUTO:
 	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 a8588fc..2c82fd9 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1734,6 +1734,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] 31+ messages in thread

* [PATCH/RFC v3 09/14] V4L: Add camera 3A lock control
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (7 preceding siblings ...)
  2012-04-27 14:23 ` [PATCH/RFC v3 08/14] V4L: Add camera scene mode control Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-30 15:59   ` Hans Verkuil
  2012-04-27 14:23 ` [PATCH/RFC v3 10/14] V4L: Add auto focus targets to the selections API Sylwester Nawrocki
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, 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 bf481d4..51509f4 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -3253,6 +3253,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 corresponding 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 control bits are defined :
+</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 the
+<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 8b48893..d45f00c 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -671,6 +671,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! */
@@ -843,6 +844,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 2c82fd9..7c30d54 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1752,6 +1752,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] 31+ messages in thread

* [PATCH/RFC v3 10/14] V4L: Add auto focus targets to the selections API
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (8 preceding siblings ...)
  2012-04-27 14:23 ` [PATCH/RFC v3 09/14] V4L: Add camera 3A lock control Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 11/14] V4L: Add auto focus targets to the subdev " Sylwester Nawrocki
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, 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 7c30d54..29b84ae 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -777,6 +777,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] 31+ messages in thread

* [PATCH/RFC v3 11/14] V4L: Add auto focus targets to the subdev selections API
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (9 preceding siblings ...)
  2012-04-27 14:23 ` [PATCH/RFC v3 10/14] V4L: Add auto focus targets to the selections API Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 12/14] V4L: Add camera auto focus controls Sylwester Nawrocki
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, 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] 31+ messages in thread

* [PATCH/RFC v3 12/14] V4L: Add camera auto focus controls
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (10 preceding siblings ...)
  2012-04-27 14:23 ` [PATCH/RFC v3 11/14] V4L: Add auto focus targets to the subdev " Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 13/14] V4L: Add S5C73M3 sensor sub-device driver Sylwester Nawrocki
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, 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 51509f4..e974a03 100644
--- a/Documentation/DocBook/media/v4l/controls.xml
+++ b/Documentation/DocBook/media/v4l/controls.xml
@@ -2902,13 +2902,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 d45f00c..da9272c 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",
@@ -656,7 +669,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";
@@ -672,6 +685,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! */
@@ -771,6 +789,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;
@@ -794,6 +814,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_AUTO_N_PRESET_WHITE_BALANCE:
 	case V4L2_CID_TUNE_PREEMPHASIS:
@@ -845,6 +867,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:
@@ -904,6 +927,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 29b84ae..3b7e995 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -1762,6 +1762,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] 31+ messages in thread

* [PATCH/RFC v3 13/14] V4L: Add S5C73M3 sensor sub-device driver
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (11 preceding siblings ...)
  2012-04-27 14:23 ` [PATCH/RFC v3 12/14] V4L: Add camera auto focus controls Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-27 14:23 ` [PATCH/RFC v3 14/14] vivi: Add controls Sylwester Nawrocki
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, 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
 - frame size enumeration
 - update to changed controls

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 |  705 +++++++++++++++
 drivers/media/video/s5c73m3/s5c73m3-spi.c   |  126 +++
 drivers/media/video/s5c73m3/s5c73m3.c       | 1243 +++++++++++++++++++++++++++
 drivers/media/video/s5c73m3/s5c73m3.h       |  442 ++++++++++
 include/media/s5c73m3.h                     |   62 ++
 8 files changed, 2590 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 f2479c5..4dd2aeb 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -556,6 +556,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 a6282a3..ef3d954 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -79,6 +79,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..06e956a
--- /dev/null
+++ b/drivers/media/video/s5c73m3/s5c73m3-ctrls.c
@@ -0,0 +1,705 @@
+/*
+ * 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 val)
+{
+	static const unsigned short wb[][2] = {
+		{ V4L2_WHITE_BALANCE_INCANDESCENT,  REG_AWB_MODE_INCANDESCENT },
+		{ V4L2_WHITE_BALANCE_FLUORESCENT,   REG_AWB_MODE_FLUORESCENT1 },
+		{ V4L2_WHITE_BALANCE_FLUORESCENT_H, REG_AWB_MODE_FLUORESCENT2 },
+		{ V4L2_WHITE_BALANCE_CLOUDY,        REG_AWB_MODE_CLOUDY },
+		{ V4L2_WHITE_BALANCE_DAYLIGHT,      REG_AWB_MODE_DAYLIGHT },
+		{ V4L2_WHITE_BALANCE_AUTO,          REG_AWB_MODE_AUTO },
+	};
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(wb); i++) {
+		if (wb[i][0] != val)
+			continue;
+
+		v4l2_dbg(1, s5c73m3_dbg, &state->subdev,
+			 "Setting white balance to: %s\n",
+			 v4l2_ctrl_get_menu(state->ctrls.auto_wb->id)[i]);
+
+		return s5c73m3_write_cmd(state, REG_AWB_MODE, wb[i][1]);
+	}
+
+	return -EINVAL;
+}
+
+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 val)
+{
+	u32 iso;
+
+	if (val == V4L2_ISO_SENSITIVITY_MANUAL)
+		iso = state->ctrls.iso->val + 1;
+	else
+		iso = 0;
+
+	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_N_PRESET_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_menu(hdl, ops,
+			V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
+			9, ~0x15e, V4L2_WHITE_BALANCE_AUTO);
+
+	/* 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_menu(hdl, ops,
+			V4L2_CID_ISO_SENSITIVITY_AUTO, 1, 0,
+			V4L2_ISO_SENSITIVITY_AUTO);
+
+	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_menu(hdl, ops,
+			V4L2_CID_WIDE_DYNAMIC_RANGE, 1, 1, 0);
+
+	ctrls->stabilization = v4l2_ctrl_new_std_menu(hdl, ops,
+			V4L2_CID_IMAGE_STABILIZATION, 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..d7ce0d7
--- /dev/null
+++ b/drivers/media/video/s5c73m3/s5c73m3.c
@@ -0,0 +1,1243 @@
+/*
+ * 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\n", on ? "on" : "off");
+		/* TODO: */
+		break;
+	case V4L2_CAPTURE_CTX_STILL:
+		v4l2_info(sd, "still capture %s\n", 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)
+{
+	struct s5c73m3 *state = subdev_to_s5c73m3(sd);
+	int i = ARRAY_SIZE(s5c73m3_formats);
+	int idx;
+
+	while (--i)
+		if (fse->code == s5c73m3_formats[i].code)
+			break;
+
+	fse->code = s5c73m3_formats[i].code;
+
+	/* FIXME: need to select pixel resolution list differently */
+	if (fse->code == V4L2_MBUS_FMT_JPEG_1X8)
+		idx = CAPTURE_IDX;
+	else
+		idx = PREVIEW_IDX;
+
+	if (fse->index >= state->pix_sizes_len[idx])
+		return -EINVAL;
+
+	fse->min_width  = state->pix_sizes[idx][fse->index].width;
+	fse->max_width  = fse->min_width;
+	fse->max_height = state->pix_sizes[idx][fse->index].height;
+	fse->min_height = fse->max_height;
+
+	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);
+
+	v4l2_info(sd, "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_ctrls = 1;
+			state->apply_fiv = 1;
+			state->apply_fmt = 1;
+		}
+	} 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);
+
+	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..f37370f
--- /dev/null
+++ b/drivers/media/video/s5c73m3/s5c73m3.h
@@ -0,0 +1,442 @@
+/*
+ * 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 v4l2_ctrl *auto_wb;
+	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] 31+ messages in thread

* [PATCH/RFC v3 14/14] vivi: Add controls
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (12 preceding siblings ...)
  2012-04-27 14:23 ` [PATCH/RFC v3 13/14] V4L: Add S5C73M3 sensor sub-device driver Sylwester Nawrocki
@ 2012-04-27 14:23 ` Sylwester Nawrocki
  2012-04-30 16:09   ` Hans Verkuil
  2012-04-30 15:10 ` [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
  2012-04-30 16:11 ` Hans Verkuil
  15 siblings, 1 reply; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-27 14:23 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, 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 d64d482..cbe103e 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;
 }
 
@@ -1267,7 +1309,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,
@@ -1290,11 +1333,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_AUTO_N_PRESET_WHITE_BALANCE,
+			9, ~0x3ff, V4L2_WHITE_BALANCE_AUTO);
+
+	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_menu(hdl, &vivi_ctrl_ops,
+			V4L2_CID_WIDE_DYNAMIC_RANGE, 1, 0, 0);
+
+	dev->stabilization = v4l2_ctrl_new_std_menu(hdl, &vivi_ctrl_ops,
+			V4L2_CID_IMAGE_STABILIZATION, 1, 0, 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] 31+ messages in thread

* Re: [PATCH/RFC v3 03/14] V4L: Add an extended camera white balance control
  2012-04-27 14:23 ` [PATCH/RFC v3 03/14] V4L: Add an extended camera white balance control Sylwester Nawrocki
@ 2012-04-27 14:30   ` Hans de Goede
  0 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2012-04-27 14:30 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: linux-media, laurent.pinchart, sakari.ailus, g.liakhovetski,
	moinejf, hverkuil, m.szyprowski, riverful.kim, sw0312.kim,
	Kyungmin Park

Hi,

Looks good!

Acked-by: Hans de Goede <hdegoede@redhat.com>

Regards,

Hans


On 04/27/2012 04:23 PM, Sylwester Nawrocki wrote:
> This patch adds V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE control which is
> an extended version of the V4L2_CID_AUTO_WHITE_BALANCE control,
> including white balance presets. The following presets are defined:
>
>   - V4L2_WHITE_BALANCE_INCANDESCENT,
>   - V4L2_WHITE_BALANCE_FLUORESCENT,
>   - V4L2_WHITE_BALANCE_FLUORESCENT_H,
>   - V4L2_WHITE_BALANCE_HORIZON,
>   - V4L2_WHITE_BALANCE_DAYLIGHT,
>   - V4L2_WHITE_BALANCE_FLASH,
>   - V4L2_WHITE_BALANCE_CLOUDY,
>   - V4L2_WHITE_BALANCE_SHADE.
>
> 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 |   70 ++++++++++++++++++++++++++
>   drivers/media/video/v4l2-ctrls.c             |   17 +++++++
>   include/linux/videodev2.h                    |   14 ++++++
>   3 files changed, 101 insertions(+)
>
> diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
> index 56a53a8..b671a70 100644
> --- a/Documentation/DocBook/media/v4l/controls.xml
> +++ b/Documentation/DocBook/media/v4l/controls.xml
> @@ -2948,6 +2948,76 @@ 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-auto-n-preset-white-balance-type">
> +	<entry spanname="id"><constant>V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE</constant>&nbsp;</entry>
> +	<entry>enum&nbsp;v4l2_auto_n_preset_white_balance_type</entry>
> +	</row><row><entry spanname="descr">Sets white balance to automatic,
> +manual or a preset. The presets determine color temperature of the light as
> +a hint to the camera for white balance adjustments resulting in most accurate
> +color representation. 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_MANUAL</constant>&nbsp;</entry>
> +		<entry>Manual white balance.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_AUTO</constant>&nbsp;</entry>
> +		<entry>Automatic white balance adjustments.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_INCANDESCENT</constant>&nbsp;</entry>
> +		<entry>White balance setting 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_FLUORESCENT</constant>&nbsp;</entry>
> +		<entry>White balance preset for fluorescent lighting.
> +It corresponds approximately to 4000...5000 K color temperature.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_FLUORESCENT_H</constant>&nbsp;</entry>
> +		<entry>With this setting the camera will compensate for
> +fluorescent H lighting.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_HORIZON</constant>&nbsp;</entry>
> +		<entry>White balance setting for horizon daylight.
> +It corresponds approximately to 5000 K color temperature.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_DAYLIGHT</constant>&nbsp;</entry>
> +		<entry>White balance preset for daylight (with clear sky).
> +It corresponds approximately to 5000...6500 K color temperature.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_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_CLOUDY</constant>&nbsp;</entry>
> +		<entry>White balance preset for moderately overcast sky.
> +This option corresponds approximately to 6500...8000 K color temperature
> +range.</entry>
> +		</row>
> +		<row>
> +		<entry><constant>V4L2_WHITE_BALANCE_SHADE</constant>&nbsp;</entry>
> +		<entry>White balance preset 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 1d7091f..02fa9b0 100644
> --- a/drivers/media/video/v4l2-ctrls.c
> +++ b/drivers/media/video/v4l2-ctrls.c
> @@ -243,6 +243,19 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
>   		"Vivid",
>   		NULL
>   	};
> +	static const char * const auto_n_preset_white_balance[] = {
> +		"Manual",
> +		"Auto",
> +		"Incandescent",
> +		"Fluorescent",
> +		"Fluorescent H",
> +		"Horizon",
> +		"Daylight",
> +		"Flash",
> +		"Cloudy",
> +		"Shade",
> +		NULL,
> +	};
>   	static const char * const tune_preemphasis[] = {
>   		"No Preemphasis",
>   		"50 Microseconds",
> @@ -412,6 +425,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
>   		return camera_exposure_auto;
>   	case V4L2_CID_COLORFX:
>   		return colorfx;
> +	case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
> +		return auto_n_preset_white_balance;
>   	case V4L2_CID_TUNE_PREEMPHASIS:
>   		return tune_preemphasis;
>   	case V4L2_CID_FLASH_LED_MODE:
> @@ -598,6 +613,7 @@ 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_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto&  Preset";
>
>   	/* FM Radio Modulator control */
>   	/* Keep the order of the 'case's the same as in videodev2.h! */
> @@ -721,6 +737,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_AUTO_N_PRESET_WHITE_BALANCE:
>   	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 da60cbb..08891e6 100644
> --- a/include/linux/videodev2.h
> +++ b/include/linux/videodev2.h
> @@ -1695,6 +1695,20 @@ enum  v4l2_exposure_auto_type {
>
>   #define V4L2_CID_AUTO_EXPOSURE_BIAS		(V4L2_CID_CAMERA_CLASS_BASE+19)
>
> +#define V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE	(V4L2_CID_CAMERA_CLASS_BASE+20)
> +enum v4l2_auto_n_preset_white_balance_type {
> +	V4L2_WHITE_BALANCE_MANUAL		= 0,
> +	V4L2_WHITE_BALANCE_AUTO			= 1,
> +	V4L2_WHITE_BALANCE_INCANDESCENT		= 2,
> +	V4L2_WHITE_BALANCE_FLUORESCENT		= 3,
> +	V4L2_WHITE_BALANCE_FLUORESCENT_H	= 4,
> +	V4L2_WHITE_BALANCE_HORIZON		= 5,
> +	V4L2_WHITE_BALANCE_DAYLIGHT		= 6,
> +	V4L2_WHITE_BALANCE_FLASH		= 7,
> +	V4L2_WHITE_BALANCE_CLOUDY		= 8,
> +	V4L2_WHITE_BALANCE_SHADE		= 9,
> +};
> +
>   /* 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] 31+ messages in thread

* Re: [PATCH/RFC v3 00/14] V4L camera control enhancements
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (13 preceding siblings ...)
  2012-04-27 14:23 ` [PATCH/RFC v3 14/14] vivi: Add controls Sylwester Nawrocki
@ 2012-04-30 15:10 ` Sylwester Nawrocki
  2012-04-30 16:11 ` Hans Verkuil
  15 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-30 15:10 UTC (permalink / raw)
  To: linux-media
  Cc: laurent.pinchart, sakari.ailus, g.liakhovetski, hdegoede,
	moinejf, hverkuil, m.szyprowski, riverful.kim, sw0312.kim,
	Sylwester Nawrocki

Hi,

On 04/27/2012 04:23 PM, Sylwester Nawrocki wrote:
> Here is one more update of the camera class controls change set.
> 
> The changes since v2 are:
>  - V4L2_CID_WHITE_BALANCE_PRESET replaced with V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE
>    according to suggestions from Hans de Goede;
>  - added Flurescent H white balance preset;
>  - V4L2_CID_IMAGE_STABILIZATION and V4L2_CID_WIDE_DYNAMIC_RANGE controls type 
>    changed from boolean to menu, to make any further extensions of these 
>    controls easier;
>    I'm just not 100% sure if V4L2_WIDE_DYNAMIC_RANGE_ENABLED and
>    V4L2_IMAGE_STABILIZATION_ENABLED are good names for cases where the camera
>    doesn't support wide dynamic range or image stabilization technique
>    selection and only allows to enable or disable those algorithms;	 
>  - V4L2_CID_ISO_SENSITIVITY_AUTO control type changed from boolean to menu in
>    order to support ISO presets; currently enum v4l2_iso_sensitivity_auto_type
>    does not contain any presets though;
>  - V4L2_CID_COLORFX patch removed from this series;
>  - updated vivi and s5c73m3 driver patches.
> 
> 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.
> 
> The patches are also available in a git repository at:
> http://git.infradead.org/users/kmpark/linux-samsung/shortlog/refs/heads/v4l-controls-s5c73m3

I've done following changes:

- V4L2_CID_AUTO_FOCUS_DISTANCE renamed to V4L2_CID_AUTO_FOCUS_RANGE,
  added new item V4L2_AUTO_FOCUS_RANGE_AUTO,
- V4L2_AUTO_FOCUS_STATUS_SUCCESS renamed to V4L2_AUTO_FOCUS_STATUS_REACHED,
  added V4L2_AUTO_FOCUS_STATUS_LOST,
- edited V4L2_CID_3A_LOCK description, renamed V4L2_3A_LOCK_* to V4L2_LOCK_*,
- added a "_type" sufffix to enum v4l2_wide_dynamic_range,
  v4l2_auto_focus_distance and v4l2_auto_focus_area,

and pushed it to git repository (gitweb link as above):
 git://git.infradead.org/users/kmpark/linux-samsung v4l-controls-s5c73m3

These are a bunch of minor changes, I didn't want to spam the mailing
list by resending whole change set again. I plan to do it at the end
of week if there are more comments and corrections needed.

--

Regards,
Sylwester

> Sylwester Nawrocki (14):
>   V4L: Add helper function for standard integer menu controls
>   V4L: Add camera exposure bias control
>   V4L: Add an extended camera white balance 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       |  501 +++++++-
>  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        |  705 +++++++++++
>  drivers/media/video/s5c73m3/s5c73m3-spi.c          |  126 ++
>  drivers/media/video/s5c73m3/s5c73m3.c              | 1243 ++++++++++++++++++++
>  drivers/media/video/s5c73m3/s5c73m3.h              |  442 +++++++
>  drivers/media/video/v4l2-ctrls.c                   |  133 ++-
>  drivers/media/video/vivi.c                         |  111 +-
>  include/linux/v4l2-subdev.h                        |    4 +
>  include/linux/videodev2.h                          |   92 ++
>  include/media/s5c73m3.h                            |   62 +
>  include/media/v4l2-ctrls.h                         |   17 +
>  19 files changed, 3536 insertions(+), 8 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

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

* Re: [PATCH/RFC v3 01/14] V4L: Add helper function for standard integer menu controls
  2012-04-27 14:23 ` [PATCH/RFC v3 01/14] V4L: Add helper function for standard integer menu controls Sylwester Nawrocki
@ 2012-04-30 15:20   ` Hans Verkuil
  2012-04-30 15:37     ` Sylwester Nawrocki
  0 siblings, 1 reply; 31+ messages in thread
From: Hans Verkuil @ 2012-04-30 15:20 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

Hi Sylwester!

Can you also update Documentation/video4linux/v4l2-controls.txt?

Thanks,

	Hans


On Friday 27 April 2012 16:23:18 Sylwester Nawrocki wrote:
> 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 c93a979..e0725b5 100644
> --- a/drivers/media/video/v4l2-ctrls.c
> +++ b/drivers/media/video/v4l2-ctrls.c
> @@ -1517,6 +1517,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 8920f82..15116d2 100644
> --- a/include/media/v4l2-ctrls.h
> +++ b/include/media/v4l2-ctrls.h
> @@ -347,6 +347,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.
> 

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

* Re: [PATCH/RFC v3 01/14] V4L: Add helper function for standard integer menu controls
  2012-04-30 15:20   ` Hans Verkuil
@ 2012-04-30 15:37     ` Sylwester Nawrocki
  0 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-04-30 15:37 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: linux-media, laurent.pinchart, sakari.ailus, g.liakhovetski,
	hdegoede, moinejf, m.szyprowski, riverful.kim, sw0312.kim,
	Kyungmin Park

Hi!

On 04/30/2012 05:20 PM, Hans Verkuil wrote:
> Hi Sylwester!
> 
> Can you also update Documentation/video4linux/v4l2-controls.txt?

I think I have to :-) I'll do, sorry for forgetting about it.

--

Regards,
Sylwester


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

* Re: [PATCH/RFC v3 04/14] V4L: Add camera wide dynamic range control
  2012-04-27 14:23 ` [PATCH/RFC v3 04/14] V4L: Add camera wide dynamic range control Sylwester Nawrocki
@ 2012-04-30 15:50   ` Hans Verkuil
  2012-04-30 15:54     ` Hans Verkuil
  0 siblings, 1 reply; 31+ messages in thread
From: Hans Verkuil @ 2012-04-30 15:50 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 Friday 27 April 2012 16:23:21 Sylwester Nawrocki wrote:
> Add V4L2_CID_WIDE_DYNAMIC_RANGE camera class control for camera wide
> dynamic range (WDR, HDR) feature. This control has now only menu entries
> for enabling and disabling WDR. It can be extended when the wide dynamic
> range technique selection is needed.
> 
> 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 |   28 ++++++++++++++++++++++++++
>  drivers/media/video/v4l2-ctrls.c             |    9 +++++++++
>  include/linux/videodev2.h                    |    6 ++++++
>  3 files changed, 43 insertions(+)
> 
> diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
> index b671a70..487b7b5 100644
> --- a/Documentation/DocBook/media/v4l/controls.xml
> +++ b/Documentation/DocBook/media/v4l/controls.xml
> @@ -3018,6 +3018,34 @@ sky. It corresponds approximately to 9000...10000 K color temperature.
>  	  </row>
>  	  <row><entry></entry></row>
>  
> +	  <row id="v4l2-wide-dynamic-range-type">
> +	    <entry spanname="id"><constant>V4L2_CID_WIDE_DYNAMIC_RANGE</constant></entry>
> +	    <entry>enum&nbsp;v4l2_wide_dynamic_range_type</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 with different exposure
> +times.</entry>
> +	  </row>
> +	  <row>
> +	    <entrytbl spanname="descr" cols="2">
> +	      <tbody valign="top">
> +		<row>
> +		  <entry><constant>V4L2_WIDE_DYNAMIC_RANGE_DISABLED</constant></entry>
> +		  <entry>Wide dynamic range is disabled.</entry>
> +		</row>
> +		<row>
> +		  <entry><constant>V4L2_WIDE_DYNAMIC_RANGE_ENABLED</constant></entry>
> +		  <entry>Wide dynamic range is enabled.</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 02fa9b0..ad2f035 100644
> --- a/drivers/media/video/v4l2-ctrls.c
> +++ b/drivers/media/video/v4l2-ctrls.c
> @@ -256,6 +256,11 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
>  		"Shade",
>  		NULL,
>  	};
> +	static const char * const camera_wide_dynamic_range[] = {
> +		"Disabled",
> +		"Enabled",
> +		NULL
> +	};

Huh? Why isn't this a boolean control? This looks very weird.

Regards,

	Hans

>  	static const char * const tune_preemphasis[] = {
>  		"No Preemphasis",
>  		"50 Microseconds",
> @@ -427,6 +432,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
>  		return colorfx;
>  	case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
>  		return auto_n_preset_white_balance;
> +	case V4L2_CID_WIDE_DYNAMIC_RANGE:
> +		return camera_wide_dynamic_range;
>  	case V4L2_CID_TUNE_PREEMPHASIS:
>  		return tune_preemphasis;
>  	case V4L2_CID_FLASH_LED_MODE:
> @@ -614,6 +621,7 @@ 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_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & 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! */
> @@ -751,6 +759,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_WIDE_DYNAMIC_RANGE:
>  		*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 08891e6..3ca9b10 100644
> --- a/include/linux/videodev2.h
> +++ b/include/linux/videodev2.h
> @@ -1709,6 +1709,12 @@ enum v4l2_auto_n_preset_white_balance_type {
>  	V4L2_WHITE_BALANCE_SHADE		= 9,
>  };
>  
> +#define V4L2_CID_WIDE_DYNAMIC_RANGE		(V4L2_CID_CAMERA_CLASS_BASE+21)
> +enum v4l2_wide_dynamic_range_type {
> +	V4L2_WIDE_DYNAMIC_RANGE_DISABLED	= 0,
> +	V4L2_WIDE_DYNAMIC_RANGE_ENABLED		= 1,
> +};
> +
>  /* 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] 31+ messages in thread

* Re: [PATCH/RFC v3 04/14] V4L: Add camera wide dynamic range control
  2012-04-30 15:50   ` Hans Verkuil
@ 2012-04-30 15:54     ` Hans Verkuil
  2012-05-01 17:33       ` Sylwester Nawrocki
  0 siblings, 1 reply; 31+ messages in thread
From: Hans Verkuil @ 2012-04-30 15:54 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 Monday 30 April 2012 17:50:57 Hans Verkuil wrote:
> On Friday 27 April 2012 16:23:21 Sylwester Nawrocki wrote:
> > Add V4L2_CID_WIDE_DYNAMIC_RANGE camera class control for camera wide
> > dynamic range (WDR, HDR) feature. This control has now only menu entries
> > for enabling and disabling WDR. It can be extended when the wide dynamic
> > range technique selection is needed.

Never mind, I get it. It's for future expansion.

That said, I find it dubious to make this an enum.

I would go with a boolean control and perhaps make a remark that it might become
an enum in the future if more options are needed.

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 |   28 ++++++++++++++++++++++++++
> >  drivers/media/video/v4l2-ctrls.c             |    9 +++++++++
> >  include/linux/videodev2.h                    |    6 ++++++
> >  3 files changed, 43 insertions(+)
> > 
> > diff --git a/Documentation/DocBook/media/v4l/controls.xml b/Documentation/DocBook/media/v4l/controls.xml
> > index b671a70..487b7b5 100644
> > --- a/Documentation/DocBook/media/v4l/controls.xml
> > +++ b/Documentation/DocBook/media/v4l/controls.xml
> > @@ -3018,6 +3018,34 @@ sky. It corresponds approximately to 9000...10000 K color temperature.
> >  	  </row>
> >  	  <row><entry></entry></row>
> >  
> > +	  <row id="v4l2-wide-dynamic-range-type">
> > +	    <entry spanname="id"><constant>V4L2_CID_WIDE_DYNAMIC_RANGE</constant></entry>
> > +	    <entry>enum&nbsp;v4l2_wide_dynamic_range_type</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 with different exposure
> > +times.</entry>
> > +	  </row>
> > +	  <row>
> > +	    <entrytbl spanname="descr" cols="2">
> > +	      <tbody valign="top">
> > +		<row>
> > +		  <entry><constant>V4L2_WIDE_DYNAMIC_RANGE_DISABLED</constant></entry>
> > +		  <entry>Wide dynamic range is disabled.</entry>
> > +		</row>
> > +		<row>
> > +		  <entry><constant>V4L2_WIDE_DYNAMIC_RANGE_ENABLED</constant></entry>
> > +		  <entry>Wide dynamic range is enabled.</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 02fa9b0..ad2f035 100644
> > --- a/drivers/media/video/v4l2-ctrls.c
> > +++ b/drivers/media/video/v4l2-ctrls.c
> > @@ -256,6 +256,11 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
> >  		"Shade",
> >  		NULL,
> >  	};
> > +	static const char * const camera_wide_dynamic_range[] = {
> > +		"Disabled",
> > +		"Enabled",
> > +		NULL
> > +	};
> 
> Huh? Why isn't this a boolean control? This looks very weird.
> 
> Regards,
> 
> 	Hans
> 
> >  	static const char * const tune_preemphasis[] = {
> >  		"No Preemphasis",
> >  		"50 Microseconds",
> > @@ -427,6 +432,8 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
> >  		return colorfx;
> >  	case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
> >  		return auto_n_preset_white_balance;
> > +	case V4L2_CID_WIDE_DYNAMIC_RANGE:
> > +		return camera_wide_dynamic_range;
> >  	case V4L2_CID_TUNE_PREEMPHASIS:
> >  		return tune_preemphasis;
> >  	case V4L2_CID_FLASH_LED_MODE:
> > @@ -614,6 +621,7 @@ 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_AUTO_N_PRESET_WHITE_BALANCE: return "White Balance, Auto & 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! */
> > @@ -751,6 +759,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_WIDE_DYNAMIC_RANGE:
> >  		*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 08891e6..3ca9b10 100644
> > --- a/include/linux/videodev2.h
> > +++ b/include/linux/videodev2.h
> > @@ -1709,6 +1709,12 @@ enum v4l2_auto_n_preset_white_balance_type {
> >  	V4L2_WHITE_BALANCE_SHADE		= 9,
> >  };
> >  
> > +#define V4L2_CID_WIDE_DYNAMIC_RANGE		(V4L2_CID_CAMERA_CLASS_BASE+21)
> > +enum v4l2_wide_dynamic_range_type {
> > +	V4L2_WIDE_DYNAMIC_RANGE_DISABLED	= 0,
> > +	V4L2_WIDE_DYNAMIC_RANGE_ENABLED		= 1,
> > +};
> > +
> >  /* 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] 31+ messages in thread

* Re: [PATCH/RFC v3 09/14] V4L: Add camera 3A lock control
  2012-04-27 14:23 ` [PATCH/RFC v3 09/14] V4L: Add camera 3A lock control Sylwester Nawrocki
@ 2012-04-30 15:59   ` Hans Verkuil
  2012-05-01 17:38     ` Sylwester Nawrocki
  0 siblings, 1 reply; 31+ messages in thread
From: Hans Verkuil @ 2012-04-30 15:59 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 Friday 27 April 2012 16:23:26 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.
> 
> 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 bf481d4..51509f4 100644
> --- a/Documentation/DocBook/media/v4l/controls.xml
> +++ b/Documentation/DocBook/media/v4l/controls.xml
> @@ -3253,6 +3253,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

Small typo: coresponding -> corresponding

> +the corresponding 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

The sentence 'The value ... focus controls' doesn't parse. I think 'other, ' needs
to be removed.

Regards,

	Hans

> +following control bits are defined :
> +</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 the
> +<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 8b48893..d45f00c 100644
> --- a/drivers/media/video/v4l2-ctrls.c
> +++ b/drivers/media/video/v4l2-ctrls.c
> @@ -671,6 +671,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! */
> @@ -843,6 +844,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 2c82fd9..7c30d54 100644
> --- a/include/linux/videodev2.h
> +++ b/include/linux/videodev2.h
> @@ -1752,6 +1752,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)
> 

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

* Re: [PATCH/RFC v3 14/14] vivi: Add controls
  2012-04-27 14:23 ` [PATCH/RFC v3 14/14] vivi: Add controls Sylwester Nawrocki
@ 2012-04-30 16:09   ` Hans Verkuil
  2012-05-01 17:40     ` Sylwester Nawrocki
  0 siblings, 1 reply; 31+ messages in thread
From: Hans Verkuil @ 2012-04-30 16:09 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 Friday 27 April 2012 16:23:31 Sylwester Nawrocki wrote:
> 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 d64d482..cbe103e 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;
> +

Why add these controls to vivi? It doesn't belong here.

Regards,

	Hans

>  	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;
>  }
>  
> @@ -1267,7 +1309,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,
> @@ -1290,11 +1333,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_AUTO_N_PRESET_WHITE_BALANCE,
> +			9, ~0x3ff, V4L2_WHITE_BALANCE_AUTO);
> +
> +	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_menu(hdl, &vivi_ctrl_ops,
> +			V4L2_CID_WIDE_DYNAMIC_RANGE, 1, 0, 0);
> +
> +	dev->stabilization = v4l2_ctrl_new_std_menu(hdl, &vivi_ctrl_ops,
> +			V4L2_CID_IMAGE_STABILIZATION, 1, 0, 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 */
> 

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

* Re: [PATCH/RFC v3 00/14] V4L camera control enhancements
  2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
                   ` (14 preceding siblings ...)
  2012-04-30 15:10 ` [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
@ 2012-04-30 16:11 ` Hans Verkuil
  2012-05-01 17:58   ` Sylwester Nawrocki
  15 siblings, 1 reply; 31+ messages in thread
From: Hans Verkuil @ 2012-04-30 16:11 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: linux-media, laurent.pinchart, sakari.ailus, g.liakhovetski,
	hdegoede, moinejf, m.szyprowski, riverful.kim, sw0312.kim

Hi Sylwester!

I've finished my review. You made excellent documentation for the new controls!

Other than some small stuff the only thing I am unhappy about is the use of menu
controls for what are currently just boolean controls.

I am inclined to make them boolean controls and add a comment that they may be
changed to menu controls in the future. That shouldn't be a problem as long as the
control values 0 and 1 retain their meaning.

Regards,

	Hans

On Friday 27 April 2012 16:23:17 Sylwester Nawrocki wrote:
> Here is one more update of the camera class controls change set.
> 
> The changes since v2 are:
>  - V4L2_CID_WHITE_BALANCE_PRESET replaced with V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE
>    according to suggestions from Hans de Goede;
>  - added Flurescent H white balance preset;
>  - V4L2_CID_IMAGE_STABILIZATION and V4L2_CID_WIDE_DYNAMIC_RANGE controls type 
>    changed from boolean to menu, to make any further extensions of these 
>    controls easier;
>    I'm just not 100% sure if V4L2_WIDE_DYNAMIC_RANGE_ENABLED and
>    V4L2_IMAGE_STABILIZATION_ENABLED are good names for cases where the camera
>    doesn't support wide dynamic range or image stabilization technique
>    selection and only allows to enable or disable those algorithms;	 
>  - V4L2_CID_ISO_SENSITIVITY_AUTO control type changed from boolean to menu in
>    order to support ISO presets; currently enum v4l2_iso_sensitivity_auto_type
>    does not contain any presets though;
>  - V4L2_CID_COLORFX patch removed from this series;
>  - updated vivi and s5c73m3 driver patches.
> 
> 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.
> 
> The patches are also available in a git repository at:
> http://git.infradead.org/users/kmpark/linux-samsung/shortlog/refs/heads/v4l-controls-s5c73m3
> 
> 
> Thanks,
> Sylwester
> 
> 
> Sylwester Nawrocki (14):
>   V4L: Add helper function for standard integer menu controls
>   V4L: Add camera exposure bias control
>   V4L: Add an extended camera white balance 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       |  501 +++++++-
>  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        |  705 +++++++++++
>  drivers/media/video/s5c73m3/s5c73m3-spi.c          |  126 ++
>  drivers/media/video/s5c73m3/s5c73m3.c              | 1243 ++++++++++++++++++++
>  drivers/media/video/s5c73m3/s5c73m3.h              |  442 +++++++
>  drivers/media/video/v4l2-ctrls.c                   |  133 ++-
>  drivers/media/video/vivi.c                         |  111 +-
>  include/linux/v4l2-subdev.h                        |    4 +
>  include/linux/videodev2.h                          |   92 ++
>  include/media/s5c73m3.h                            |   62 +
>  include/media/v4l2-ctrls.h                         |   17 +
>  19 files changed, 3536 insertions(+), 8 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
> 
> 

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

* Re: [PATCH/RFC v3 04/14] V4L: Add camera wide dynamic range control
  2012-04-30 15:54     ` Hans Verkuil
@ 2012-05-01 17:33       ` Sylwester Nawrocki
  0 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-05-01 17:33 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sylwester Nawrocki, linux-media, laurent.pinchart, sakari.ailus,
	g.liakhovetski, hdegoede, moinejf, m.szyprowski, riverful.kim,
	sw0312.kim, Kyungmin Park

Hi Hans,

On 04/30/2012 05:54 PM, Hans Verkuil wrote:
> On Monday 30 April 2012 17:50:57 Hans Verkuil wrote:
>> On Friday 27 April 2012 16:23:21 Sylwester Nawrocki wrote:
>>> Add V4L2_CID_WIDE_DYNAMIC_RANGE camera class control for camera wide
>>> dynamic range (WDR, HDR) feature. This control has now only menu entries
>>> for enabling and disabling WDR. It can be extended when the wide dynamic
>>> range technique selection is needed.
> 
> Never mind, I get it. It's for future expansion.
> 
> That said, I find it dubious to make this an enum.
> 
> I would go with a boolean control and perhaps make a remark that it might 
> become an enum in the future if more options are needed.

Yes, my intention was to have something that would be easy to expand 
without ABI perturbations. I believe in future there may be more 
detailed control needed, than just WDR enable/disable. 

Thanks for the suggestion, I'll revert this back to a boolean type
and add proper note in the documentation.

--

Regards,
Sylwester

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

* Re: [PATCH/RFC v3 09/14] V4L: Add camera 3A lock control
  2012-04-30 15:59   ` Hans Verkuil
@ 2012-05-01 17:38     ` Sylwester Nawrocki
  0 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-05-01 17:38 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sylwester Nawrocki, linux-media, laurent.pinchart, sakari.ailus,
	g.liakhovetski, hdegoede, moinejf, m.szyprowski, riverful.kim,
	sw0312.kim, Kyungmin Park

On 04/30/2012 05:59 PM, Hans Verkuil wrote:
> On Friday 27 April 2012 16:23:26 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.
>>
>> 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 bf481d4..51509f4 100644
>> --- a/Documentation/DocBook/media/v4l/controls.xml
>> +++ b/Documentation/DocBook/media/v4l/controls.xml
>> @@ -3253,6 +3253,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
> 
> Small typo: coresponding ->  corresponding

Ok, thanks for pointing out. I've just found a few more by running 
spell checker on everything again.

>> +the corresponding 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
> 
> The sentence 'The value ... focus controls' doesn't parse. I think 'other, ' needs
> to be removed.

Yeah, indeed, I'll correct that. I have already edited this paragraph 
and this sentence is gone. That's a new version:
http://git.infradead.org/users/kmpark/linux-samsung/commitdiff/95444f3180570186a11b9c6d2643d5644f0e8b21

I'm going to leave the sentence though, and remove this one instead:

"The locks have highest priority and must be disabled when automatic 
camera settings are required."

Since a use case with V4L2_CID_3A_LOCK having "top priority" could 
be modelled with the control flags. And it might be hard to predict 
how the controls interact with each other among various cameras.

--

Thanks,
Sylwester

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

* Re: [PATCH/RFC v3 14/14] vivi: Add controls
  2012-04-30 16:09   ` Hans Verkuil
@ 2012-05-01 17:40     ` Sylwester Nawrocki
  2012-05-01 17:48       ` Hans Verkuil
  0 siblings, 1 reply; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-05-01 17:40 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sylwester Nawrocki, linux-media, laurent.pinchart, sakari.ailus,
	g.liakhovetski, hdegoede, moinejf, m.szyprowski, riverful.kim,
	sw0312.kim, Kyungmin Park

On 04/30/2012 06:09 PM, Hans Verkuil wrote:
> On Friday 27 April 2012 16:23:31 Sylwester Nawrocki wrote:
>> 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 d64d482..cbe103e 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;
>> +
> 
> Why add these controls to vivi? It doesn't belong here.

Yeah, my intention was to provide some basic means for validating the
new controls, especially integer menu ones. I really don't use vivi 
for testing, but I think not many people have currently access to the
hardware I work with. So this is just in case Mauro wants to do tests
of the core control framework changes. I agree this patch doesn't 
make sense for anything other than that.

I have also a small patch for v4l2-ctl to support integer menu 
control enumeration. However I run into some weird problems when
I cross compiled it for ARM (individual menu names are not listed)
and didn't get around to fix that yet. So I didn't yet send that 
v4l2-ctl patch out.

--

Regards,
Sylwester

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

* Re: [PATCH/RFC v3 14/14] vivi: Add controls
  2012-05-01 17:40     ` Sylwester Nawrocki
@ 2012-05-01 17:48       ` Hans Verkuil
  2012-05-01 18:27         ` Sylwester Nawrocki
  0 siblings, 1 reply; 31+ messages in thread
From: Hans Verkuil @ 2012-05-01 17:48 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: Sylwester Nawrocki, linux-media, laurent.pinchart, sakari.ailus,
	g.liakhovetski, hdegoede, moinejf, m.szyprowski, riverful.kim,
	sw0312.kim, Kyungmin Park

On Tue May 1 2012 19:40:55 Sylwester Nawrocki wrote:
> On 04/30/2012 06:09 PM, Hans Verkuil wrote:
> > On Friday 27 April 2012 16:23:31 Sylwester Nawrocki wrote:
> >> 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 d64d482..cbe103e 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;
> >> +
> > 
> > Why add these controls to vivi? It doesn't belong here.
> 
> Yeah, my intention was to provide some basic means for validating the
> new controls, especially integer menu ones. I really don't use vivi 
> for testing, but I think not many people have currently access to the
> hardware I work with. So this is just in case Mauro wants to do tests
> of the core control framework changes. I agree this patch doesn't 
> make sense for anything other than that.
> 
> I have also a small patch for v4l2-ctl to support integer menu 
> control enumeration. However I run into some weird problems when
> I cross compiled it for ARM (individual menu names are not listed)
> and didn't get around to fix that yet. So I didn't yet send that 
> v4l2-ctl patch out.

There is already an int-menu control in vivi, and v4l2-ctl already
support integer menus as well (as does qv4l2 and v4l2-compliance).

So this should be all ready for you.

BTW, it would be nice to get g/s_selection support in v4l2-ctl, that is
still missing. And a good test in v4l2-compliance would be great as well.

Have you run v4l2-compliance lately? It's getting pretty good at catching
all sorts of inconsistencies.

Regards,

	Hans

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

* Re: [PATCH/RFC v3 00/14] V4L camera control enhancements
  2012-04-30 16:11 ` Hans Verkuil
@ 2012-05-01 17:58   ` Sylwester Nawrocki
  0 siblings, 0 replies; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-05-01 17:58 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sylwester Nawrocki, linux-media, laurent.pinchart, sakari.ailus,
	g.liakhovetski, hdegoede, moinejf, m.szyprowski, riverful.kim,
	sw0312.kim

Hi Hans,

On 04/30/2012 06:11 PM, Hans Verkuil wrote:
> Hi Sylwester!
> 
> I've finished my review. You made excellent documentation for the new controls!

Thank you, and thanks for your time! :-) It took me quite a few hours to prepare 
it, and lack of proper sensor datasheets didn't make this task any easier.

> Other than some small stuff the only thing I am unhappy about is the use of menu
> controls for what are currently just boolean controls.
> 
> I am inclined to make them boolean controls and add a comment that they may be
> changed to menu controls in the future. That shouldn't be a problem as long as 
> the control values 0 and 1 retain their meaning.

OK, I like the idea. The menus looked rather ugly, I agree. I'll revert 
those controls back to a boolean type and add a small note in the 
documentation. In fact this solves one of the major open issues I had.

I tried to align start of second columns in the nested 2-column tables
(<entrytbl></entrytbl>) containing a menu item identifiers and their
description. I tried 'align', 'colspec', 'spanspec' but could get 
expected results and I gave up, spending hours on modify/re-compile.
I couldn't even enable the column border inside 'entrytbl'. I could 
only align the columns by getting rid of 'entrytbl', but that's not
a solution. It doesn't look that bad with different indentation at
each control's description after all, maybe I'll find some time to 
dig in it later.

I'm going to incorporate all comments and resend whole patch set at 
end of the week.

--

Regards,
Sylwester

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

* Re: [PATCH/RFC v3 14/14] vivi: Add controls
  2012-05-01 17:48       ` Hans Verkuil
@ 2012-05-01 18:27         ` Sylwester Nawrocki
  2012-05-01 19:02           ` Hans Verkuil
  0 siblings, 1 reply; 31+ messages in thread
From: Sylwester Nawrocki @ 2012-05-01 18:27 UTC (permalink / raw)
  To: Hans Verkuil
  Cc: Sylwester Nawrocki, linux-media, laurent.pinchart, sakari.ailus,
	g.liakhovetski, hdegoede, moinejf, m.szyprowski, riverful.kim,
	sw0312.kim, Kyungmin Park

On 05/01/2012 07:48 PM, Hans Verkuil wrote:
> On Tue May 1 2012 19:40:55 Sylwester Nawrocki wrote:
>> On 04/30/2012 06:09 PM, Hans Verkuil wrote:
>>> On Friday 27 April 2012 16:23:31 Sylwester Nawrocki wrote:
...
>>> Why add these controls to vivi? It doesn't belong here.
>>
>> Yeah, my intention was to provide some basic means for validating the
>> new controls, especially integer menu ones. I really don't use vivi
>> for testing, but I think not many people have currently access to the
>> hardware I work with. So this is just in case Mauro wants to do tests
>> of the core control framework changes. I agree this patch doesn't
>> make sense for anything other than that.
>>
>> I have also a small patch for v4l2-ctl to support integer menu
>> control enumeration. However I run into some weird problems when
>> I cross compiled it for ARM (individual menu names are not listed)
>> and didn't get around to fix that yet. So I didn't yet send that
>> v4l2-ctl patch out.
> 
> There is already an int-menu control in vivi, and v4l2-ctl already
> support integer menus as well (as does qv4l2 and v4l2-compliance).
> 
> So this should be all ready for you.

Oh, it is there already! Must have been too busy to notice that :/

> BTW, it would be nice to get g/s_selection support in v4l2-ctl, that is
> still missing. And a good test in v4l2-compliance would be great as well.

Yeah, I noticed that too recently, we use selections on video nodes 
in some drivers and media-ctl can be only used for subdevs. I'll try
to find some time to add selection ioctls support to v4l2-ctl first,
perhaps this weekend.

> Have you run v4l2-compliance lately? It's getting pretty good at 
> catching all sorts of inconsistencies.

No, I haven't used it for a while. I know from the last run I need to
add G/S_PRIORITY support in one of the drivers. :)

I'm going to give it a try, however I'm going to need to deal with 
more and more media controller nodes. For example the fimc-lite
camera host driver I posted recently can be used with media controller
API only, I set only V4L2_CAP_STREAMING at the video node, as it was 
agreed previously. I assume some support for media controller API 
needs to be added to v4l2-compliance as well ?

--

Regards,
Sylwester

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

* Re: [PATCH/RFC v3 14/14] vivi: Add controls
  2012-05-01 18:27         ` Sylwester Nawrocki
@ 2012-05-01 19:02           ` Hans Verkuil
  0 siblings, 0 replies; 31+ messages in thread
From: Hans Verkuil @ 2012-05-01 19:02 UTC (permalink / raw)
  To: Sylwester Nawrocki
  Cc: Sylwester Nawrocki, linux-media, laurent.pinchart, sakari.ailus,
	g.liakhovetski, hdegoede, moinejf, m.szyprowski, riverful.kim,
	sw0312.kim, Kyungmin Park

On Tue May 1 2012 20:27:56 Sylwester Nawrocki wrote:
> On 05/01/2012 07:48 PM, Hans Verkuil wrote:
> > On Tue May 1 2012 19:40:55 Sylwester Nawrocki wrote:
> >> On 04/30/2012 06:09 PM, Hans Verkuil wrote:
> >>> On Friday 27 April 2012 16:23:31 Sylwester Nawrocki wrote:
> ...
> >>> Why add these controls to vivi? It doesn't belong here.
> >>
> >> Yeah, my intention was to provide some basic means for validating the
> >> new controls, especially integer menu ones. I really don't use vivi
> >> for testing, but I think not many people have currently access to the
> >> hardware I work with. So this is just in case Mauro wants to do tests
> >> of the core control framework changes. I agree this patch doesn't
> >> make sense for anything other than that.
> >>
> >> I have also a small patch for v4l2-ctl to support integer menu
> >> control enumeration. However I run into some weird problems when
> >> I cross compiled it for ARM (individual menu names are not listed)
> >> and didn't get around to fix that yet. So I didn't yet send that
> >> v4l2-ctl patch out.
> > 
> > There is already an int-menu control in vivi, and v4l2-ctl already
> > support integer menus as well (as does qv4l2 and v4l2-compliance).
> > 
> > So this should be all ready for you.
> 
> Oh, it is there already! Must have been too busy to notice that :/
> 
> > BTW, it would be nice to get g/s_selection support in v4l2-ctl, that is
> > still missing. And a good test in v4l2-compliance would be great as well.
> 
> Yeah, I noticed that too recently, we use selections on video nodes 
> in some drivers and media-ctl can be only used for subdevs. I'll try
> to find some time to add selection ioctls support to v4l2-ctl first,
> perhaps this weekend.
> 
> > Have you run v4l2-compliance lately? It's getting pretty good at 
> > catching all sorts of inconsistencies.
> 
> No, I haven't used it for a while. I know from the last run I need to
> add G/S_PRIORITY support in one of the drivers. :)
> 
> I'm going to give it a try, however I'm going to need to deal with 
> more and more media controller nodes. For example the fimc-lite
> camera host driver I posted recently can be used with media controller
> API only, I set only V4L2_CAP_STREAMING at the video node, as it was 
> agreed previously. I assume some support for media controller API 
> needs to be added to v4l2-compliance as well ?

Yes, that's true.

Note that the purpose of v4l2-compliance is primarily to test the API: i.e.
are all the fields filled in correctly and consistently. It's not really meant
to test streaming (although some support for that needs to be added at some
point in time).

In practice problems with streaming are quickly discovered, it's the little
things like not filling in all the fields correctly that are much harder to
find.

Regards,

	Hans

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

end of thread, other threads:[~2012-05-01 19:02 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-27 14:23 [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 01/14] V4L: Add helper function for standard integer menu controls Sylwester Nawrocki
2012-04-30 15:20   ` Hans Verkuil
2012-04-30 15:37     ` Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 02/14] V4L: Add camera exposure bias control Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 03/14] V4L: Add an extended camera white balance control Sylwester Nawrocki
2012-04-27 14:30   ` Hans de Goede
2012-04-27 14:23 ` [PATCH/RFC v3 04/14] V4L: Add camera wide dynamic range control Sylwester Nawrocki
2012-04-30 15:50   ` Hans Verkuil
2012-04-30 15:54     ` Hans Verkuil
2012-05-01 17:33       ` Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 05/14] V4L: Add camera image stabilization control Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 06/14] V4L: Add camera ISO sensitivity controls Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 07/14] V4L: Add camera exposure metering control Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 08/14] V4L: Add camera scene mode control Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 09/14] V4L: Add camera 3A lock control Sylwester Nawrocki
2012-04-30 15:59   ` Hans Verkuil
2012-05-01 17:38     ` Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 10/14] V4L: Add auto focus targets to the selections API Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 11/14] V4L: Add auto focus targets to the subdev " Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 12/14] V4L: Add camera auto focus controls Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 13/14] V4L: Add S5C73M3 sensor sub-device driver Sylwester Nawrocki
2012-04-27 14:23 ` [PATCH/RFC v3 14/14] vivi: Add controls Sylwester Nawrocki
2012-04-30 16:09   ` Hans Verkuil
2012-05-01 17:40     ` Sylwester Nawrocki
2012-05-01 17:48       ` Hans Verkuil
2012-05-01 18:27         ` Sylwester Nawrocki
2012-05-01 19:02           ` Hans Verkuil
2012-04-30 15:10 ` [PATCH/RFC v3 00/14] V4L camera control enhancements Sylwester Nawrocki
2012-04-30 16:11 ` Hans Verkuil
2012-05-01 17:58   ` 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.