Skip to contentSkip to conversation

V4L2 subdev and sensor control changes, SMIA++ driver and N9 camera board code

RFC In review Sakari Ailus 5 participants 76 messages Dec 20, 2011 – Jan 16, 2012

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

cover V4L2 subdev and sensor control changes, SMIA++ driver and N9 camera board code

Hi everyone,

This patchset contains new versions of a couple of previous patchsets I've sent to the list recently. There are mostly minor changes to many existing patches based on the comments I've got so far, so I'm resending them. The list is here:

- Integer menu controls [2],
- Selection IOCTL for subdevs [3],
- Sensor control changes [5],
- validate_pipeline() V4L2 subdev pad op,
- OMAP 3 ISP driver improvements [4],
- SMIA++ sensor driver and
- rm680/rm696 board code (a.k.a Nokia N9 and N950)

More detailed information can be found in the references. I'm still sending the set as RFC since it contains many patches which I would like to get more comments on, especially the changes related to V4L2.

This patchset depends on Aaro Koskinen's N9 patchset [1] to actually function at least on the N9. That, to my understanding, is on its way to mainline.

Comments and questions are very, very welcome.

References:

[1] http://www.spinics.net/lists/linux-omap/msg61295.html

[2] http://www.spinics.net/lists/linux-media/msg40796.html

[3] http://www.spinics.net/lists/linux-media/msg41503.html

[4] http://www.spinics.net/lists/linux-media/msg41542.html

[5] http://www.spinics.net/lists/linux-media/msg40861.html

Kind regards,

Signature · 2 lines
Sakari Ailus
[email protected]
#1 lore raw

RFC 1/17 v4l: Introduce integer menu controls

From: Sakari Ailus <[email protected]>

Create a new control type called V4L2_CTRL_TYPE_INTEGER_MENU. Integer menu controls are just like menu controls but the menu items are 64-bit integers rather than strings.

---
 drivers/media/video/v4l2-ctrls.c |   60 +++++++++++++++++++++++++++----------
 include/linux/videodev2.h        |    6 +++-
 include/media/v4l2-ctrls.h       |    6 +++-
 3 files changed, 54 insertions(+), 18 deletions(-)
drivers/media/video/v4l2-ctrls.c +44 -16
index 0f415da..083bb79 100644
@@ -804,7 +804,8 @@ static void fill_event(struct v4l2_event *ev, struct v4l2_ctrl *ctrl, u32 change
 		ev->u.ctrl.value64 = ctrl->cur.val64;
 	ev->u.ctrl.minimum = ctrl->minimum;
 	ev->u.ctrl.maximum = ctrl->maximum;
-	if (ctrl->type == V4L2_CTRL_TYPE_MENU)
+	if (ctrl->type == V4L2_CTRL_TYPE_MENU
+	    || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU)
 		ev->u.ctrl.step = 1;
 	else
 		ev->u.ctrl.step = ctrl->step;
@@ -1035,10 +1036,13 @@ static int validate_new_int(const struct v4l2_ctrl *ctrl, s32 *pval)
 		return 0;
 
 	case V4L2_CTRL_TYPE_MENU:
+	case V4L2_CTRL_TYPE_INTEGER_MENU:
 		if (val < ctrl->minimum || val > ctrl->maximum)
 			return -ERANGE;
-		if (ctrl->qmenu[val][0] == '\0' ||
-		    (ctrl->menu_skip_mask & (1 << val)))
+		if (ctrl->menu_skip_mask & (1 << val))
+			return -EINVAL;
+		if (ctrl->type == V4L2_CTRL_TYPE_MENU &&
+		    ctrl->qmenu[val][0] == '\0')
 			return -EINVAL;
 		return 0;
 
@@ -1295,7 +1299,8 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
 			const struct v4l2_ctrl_ops *ops,
 			u32 id, const char *name, enum v4l2_ctrl_type type,
 			s32 min, s32 max, u32 step, s32 def,
-			u32 flags, const char * const *qmenu, void *priv)
+			u32 flags, const char * const *qmenu,
+			const s64 *qmenu_int, void *priv)
 {
 	struct v4l2_ctrl *ctrl;
 	unsigned sz_extra = 0;
@@ -1308,6 +1313,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
 	    (type == V4L2_CTRL_TYPE_INTEGER && step == 0) ||
 	    (type == V4L2_CTRL_TYPE_BITMASK && max == 0) ||
 	    (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) ||
+	    (type == V4L2_CTRL_TYPE_INTEGER_MENU && qmenu_int == NULL) ||
 	    (type == V4L2_CTRL_TYPE_STRING && max == 0)) {
 		handler_set_err(hdl, -ERANGE);
 		return NULL;
@@ -1318,6 +1324,7 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
 	}
 	if ((type == V4L2_CTRL_TYPE_INTEGER ||
 	     type == V4L2_CTRL_TYPE_MENU ||
+	     type == V4L2_CTRL_TYPE_INTEGER_MENU ||
 	     type == V4L2_CTRL_TYPE_BOOLEAN) &&
 	    (def < min || def > max)) {
 		handler_set_err(hdl, -ERANGE);
@@ -1352,7 +1359,10 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
 	ctrl->minimum = min;
 	ctrl->maximum = max;
 	ctrl->step = step;
-	ctrl->qmenu = qmenu;
+	if (type == V4L2_CTRL_TYPE_MENU)
+		ctrl->qmenu = qmenu;
+	else if (type == V4L2_CTRL_TYPE_INTEGER_MENU)
+		ctrl->qmenu_int = qmenu_int;
 	ctrl->priv = priv;
 	ctrl->cur.val = ctrl->val = ctrl->default_value = def;
 
@@ -1379,6 +1389,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
 	struct v4l2_ctrl *ctrl;
 	const char *name = cfg->name;
 	const char * const *qmenu = cfg->qmenu;
+	const s64 *qmenu_int = cfg->qmenu_int;
 	enum v4l2_ctrl_type type = cfg->type;
 	u32 flags = cfg->flags;
 	s32 min = cfg->min;
@@ -1390,18 +1401,24 @@ struct v4l2_ctrl *v4l2_ctrl_new_custom(struct v4l2_ctrl_handler *hdl,
 		v4l2_ctrl_fill(cfg->id, &name, &type, &min, &max, &step,
 								&def, &flags);
 
-	is_menu = (cfg->type == V4L2_CTRL_TYPE_MENU);
+	is_menu = (cfg->type == V4L2_CTRL_TYPE_MENU ||
+		   cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU);
 	if (is_menu)
 		WARN_ON(step);
 	else
 		WARN_ON(cfg->menu_skip_mask);
-	if (is_menu && qmenu == NULL)
+	if (cfg->type == V4L2_CTRL_TYPE_MENU && qmenu == NULL)
 		qmenu = v4l2_ctrl_get_menu(cfg->id);
+	else if (cfg->type == V4L2_CTRL_TYPE_INTEGER_MENU &&
+		 qmenu_int == NULL) {
+		handler_set_err(hdl, -EINVAL);
+		return NULL;
+	}
 
 	ctrl = v4l2_ctrl_new(hdl, cfg->ops, cfg->id, name,
 			type, min, max,
 			is_menu ? cfg->menu_skip_mask : step,
-			def, flags, qmenu, priv);
+			def, flags, qmenu, qmenu_int, priv);
 	if (ctrl)
 		ctrl->is_private = cfg->is_private;
 	return ctrl;
@@ -1418,12 +1435,13 @@ struct v4l2_ctrl *v4l2_ctrl_new_std(struct v4l2_ctrl_handler *hdl,
 	u32 flags;
 
 	v4l2_ctrl_fill(id, &name, &type, &min, &max, &step, &def, &flags);
-	if (type == V4L2_CTRL_TYPE_MENU) {
+	if (type == V4L2_CTRL_TYPE_MENU
+	    || type == V4L2_CTRL_TYPE_INTEGER_MENU) {
 		handler_set_err(hdl, -EINVAL);
 		return NULL;
 	}
 	return v4l2_ctrl_new(hdl, ops, id, name, type,
-				    min, max, step, def, flags, NULL, NULL);
+			     min, max, step, def, flags, NULL, NULL, NULL);
 }
 EXPORT_SYMBOL(v4l2_ctrl_new_std);
 
@@ -1445,7 +1463,7 @@ struct v4l2_ctrl *v4l2_ctrl_new_std_menu(struct v4l2_ctrl_handler *hdl,
 		return NULL;
 	}
 	return v4l2_ctrl_new(hdl, ops, id, name, type,
-				    0, max, mask, def, flags, qmenu, NULL);
+			     0, max, mask, def, flags, qmenu, NULL, NULL);
 }
 EXPORT_SYMBOL(v4l2_ctrl_new_std_menu);
 
@@ -1609,6 +1627,9 @@ static void log_ctrl(const struct v4l2_ctrl *ctrl,
 	case V4L2_CTRL_TYPE_MENU:
 		printk(KERN_CONT "%s", ctrl->qmenu[ctrl->cur.val]);
 		break;
+	case V4L2_CTRL_TYPE_INTEGER_MENU:
+		printk(KERN_CONT "%lld", ctrl->qmenu_int[ctrl->cur.val]);
+		break;
 	case V4L2_CTRL_TYPE_BITMASK:
 		printk(KERN_CONT "0x%08x", ctrl->cur.val);
 		break;
@@ -1745,7 +1766,8 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
 	qc->minimum = ctrl->minimum;
 	qc->maximum = ctrl->maximum;
 	qc->default_value = ctrl->default_value;
-	if (ctrl->type == V4L2_CTRL_TYPE_MENU)
+	if (ctrl->type == V4L2_CTRL_TYPE_MENU
+	    || ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU)
 		qc->step = 1;
 	else
 		qc->step = ctrl->step;
@@ -1775,16 +1797,22 @@ int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm)
 
 	qm->reserved = 0;
 	/* Sanity checks */
-	if (ctrl->qmenu == NULL ||
+	if ((ctrl->type == V4L2_CTRL_TYPE_MENU && ctrl->qmenu == NULL) ||
+	    (ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU
+	     && ctrl->qmenu_int == NULL) ||
 	    i < ctrl->minimum || i > ctrl->maximum)
 		return -EINVAL;
 	/* Use mask to see if this menu item should be skipped */
 	if (ctrl->menu_skip_mask & (1 << i))
 		return -EINVAL;
 	/* Empty menu items should also be skipped */
-	if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0')
-		return -EINVAL;
-	strlcpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
+	if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
+		if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0')
+			return -EINVAL;
+		strlcpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
+	} else if (ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) {
+		qm->value = ctrl->qmenu_int[i];
+	}
 	return 0;
 }
 EXPORT_SYMBOL(v4l2_querymenu);
include/linux/videodev2.h +5 -1
index 4b752d5..9633c69 100644
@@ -1094,6 +1094,7 @@ enum v4l2_ctrl_type {
 	V4L2_CTRL_TYPE_CTRL_CLASS    = 6,
 	V4L2_CTRL_TYPE_STRING        = 7,
 	V4L2_CTRL_TYPE_BITMASK       = 8,
+	V4L2_CTRL_TYPE_INTEGER_MENU = 9,
 };
 
 /*  Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
@@ -1113,7 +1114,10 @@ struct v4l2_queryctrl {
 struct v4l2_querymenu {
 	__u32		id;
 	__u32		index;
-	__u8		name[32];	/* Whatever */
+	union {
+		__u8	name[32];	/* Whatever */
+		__s64	value;
+	};
 	__u32		reserved;
 };
 
include/media/v4l2-ctrls.h +5 -1
index eeb3df6..f7819e7 100644
@@ -129,7 +129,10 @@ struct v4l2_ctrl {
 		u32 step;
 		u32 menu_skip_mask;
 	};
-	const char * const *qmenu;
+	union {
+		const char * const *qmenu;
+		const s64 *qmenu_int;
+	};
 	unsigned long flags;
 	union {
 		s32 val;
@@ -219,6 +222,7 @@ struct v4l2_ctrl_config {
 	u32 flags;
 	u32 menu_skip_mask;
 	const char * const *qmenu;
+	const s64 *qmenu_int;
 	unsigned int is_private:1;
 };
 
Signature · 1 line
1.7.2.5
#2 lore raw

Re: [RFC 01/17] v4l: Introduce integer menu controls

Hi Sakari,

Thanks for the patch.

Quoted 5 lines · On Tuesday 20 December 2011 21:27:53 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Create a new control type called V4L2_CTRL_TYPE_INTEGER_MENU. Integer menu controls are just like menu controls but the menu items are 64-bit integers rather than strings.

[snip]

drivers/media/video/v4l2-ctrls.c int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, · line 1800

Quoted 10 lines
(quoted diff) +0 -0

b/drivers/media/video/v4l2-ctrls.c index 0f415da..083bb79 100644

drivers/media/video/v4l2-ctrls.c +0 -0
@@ -1775,16 +1797,22 @@ int v4l2_querymenu(struct v4l2_ctrl_handler *hdl,
 struct v4l2_querymenu *qm)
 
 	qm->reserved = 0;
 	/* Sanity checks */

You should return -EINVAL here if the control is not of a menu type. It was done implictly before by the ctrl->qmenu == NULL check, but that's now conditioned to the control type being V4L2_CTRL_TYPE_MENU.

Quoted 8 lines
drivers/media/video/v4l2-ctrls.c +3 -1
-	if (ctrl->qmenu == NULL ||
+	if ((ctrl->type == V4L2_CTRL_TYPE_MENU && ctrl->qmenu == NULL) ||
+	    (ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU
+	     && ctrl->qmenu_int == NULL) ||
 	    i < ctrl->minimum || i > ctrl->maximum)
 		return -EINVAL;
 	/* Use mask to see if this menu item should be skipped */
 	if (ctrl->menu_skip_mask & (1 << i))

drivers/media/video/v4l2-ctrls.c int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm) · line 1813

Quoted 10 lines
drivers/media/video/v4l2-ctrls.c +5 -3
 		return -EINVAL;
 	/* Empty menu items should also be skipped */
-	if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0')
-		return -EINVAL;
-	strlcpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
+	if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
+		if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0')
+			return -EINVAL;
+		strlcpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
+	} else if (ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) {

And you can then replace the else if by an else.

Quoted 5 lines
drivers/media/video/v4l2-ctrls.c +2 -0
+		qm->value = ctrl->qmenu_int[i];
+	}
 	return 0;
 }

EXPORT_SYMBOL(v4l2_querymenu);

Signature · 3 lines
Regards,

Laurent Pinchart
#3 lore raw

Re: [RFC 01/17] v4l: Introduce integer menu controls

Hi Laurent,

Quoted 3 lines · Laurent Pinchart

Hi Sakari,

Thanks for the patch.

Thanks for the review!

Quoted 17 lines · On Tuesday 20 December 2011 21:27:53 Sakari Ailus wrote:
Quoted 5 lines

From: Sakari Ailus <[email protected]>

Create a new control type called V4L2_CTRL_TYPE_INTEGER_MENU. Integer menu controls are just like menu controls but the menu items are 64-bit integers rather than strings.

[snip]

Quoted 8 lines
(quoted diff) +0 -0

b/drivers/media/video/v4l2-ctrls.c index 0f415da..083bb79 100644

drivers/media/video/v4l2-ctrls.c +0 -0
@@ -1775,16 +1797,22 @@ int v4l2_querymenu(struct v4l2_ctrl_handler *hdl,
 struct v4l2_querymenu *qm)
 
Quoted 6 lines

drivers/media/video/v4l2-ctrls.c int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm) · line 1799

Quoted 2 lines
drivers/media/video/v4l2-ctrls.c +0 -0
 	qm->reserved = 0;
 	/* Sanity checks */

You should return -EINVAL here if the control is not of a menu type. It was done implictly before by the ctrl->qmenu == NULL check, but that's now conditioned to the control type being V4L2_CTRL_TYPE_MENU.

Good point. Fixed.

Quoted 12 lines
Quoted 12 lines
drivers/media/video/v4l2-ctrls.c +3 -3
-	if (ctrl->qmenu == NULL ||
+	if ((ctrl->type == V4L2_CTRL_TYPE_MENU && ctrl->qmenu == NULL) ||
+	    (ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU
+	     && ctrl->qmenu_int == NULL) ||
 	    i < ctrl->minimum || i > ctrl->maximum)
 		return -EINVAL;
 	/* Use mask to see if this menu item should be skipped */
 	if (ctrl->menu_skip_mask & (1 << i))
 		return -EINVAL;
 	/* Empty menu items should also be skipped */
-	if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0')
-		return -EINVAL;
Quoted 8 lines

drivers/media/video/v4l2-ctrls.c int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm) · line 1813

Quoted 6 lines
drivers/media/video/v4l2-ctrls.c +5 -1
-	strlcpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
+	if (ctrl->type == V4L2_CTRL_TYPE_MENU) {
+		if (ctrl->qmenu[i] == NULL || ctrl->qmenu[i][0] == '\0')
+			return -EINVAL;
+		strlcpy(qm->name, ctrl->qmenu[i], sizeof(qm->name));
+	} else if (ctrl->type == V4L2_CTRL_TYPE_INTEGER_MENU) {

And you can then replace the else if by an else.

As well as this one.

Quoted 6 lines
Quoted 5 lines
drivers/media/video/v4l2-ctrls.c +2 -0
+		qm->value = ctrl->qmenu_int[i];
+	}
 	return 0;
 }

EXPORT_SYMBOL(v4l2_querymenu);

Signature · 2 lines
Sakari Ailus
[email protected]
#4 lore raw

RFC 2/17 v4l: Document integer menu controls

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

---
 Documentation/DocBook/media/v4l/compat.xml         |   10 +++++
 Documentation/DocBook/media/v4l/v4l2.xml           |    7 ++++
 .../DocBook/media/v4l/vidioc-queryctrl.xml         |   39 +++++++++++++++++++-
 3 files changed, 54 insertions(+), 2 deletions(-)
Documentation/DocBook/media/v4l/compat.xml +10 -0
index b68698f..569efd1 100644
@@ -2379,6 +2379,16 @@ that used it. It was originally scheduled for removal in 2.6.35.
       </orderedlist>
     </section>
 
+    <section>
+      <title>V4L2 in Linux 3.3</title>
+      <orderedlist>
+        <listitem>
+	  <para>Added integer menus, the new type will be
+	  V4L2_CTRL_TYPE_INTEGER_MENU.</para>
+        </listitem>
+      </orderedlist>
+    </section>
+
     <section id="other">
       <title>Relation of V4L2 to other Linux multimedia APIs</title>
 
Documentation/DocBook/media/v4l/v4l2.xml +7 -0
index 2ab365c..affe1ba 100644
@@ -128,6 +128,13 @@ structs, ioctls) must be noted in more detail in the history chapter
 applications. -->
 
       <revision>
+	<revnumber>3.3</revnumber>
+	<date>2011-11-24</date>
+	<authorinitials>sa</authorinitials>
+	<revremark>Added V4L2_CTRL_TYPE_INTEGER_MENU.</revremark>
+      </revision>
+
+      <revision>
 	<revnumber>3.2</revnumber>
 	<date>2011-08-26</date>
 	<authorinitials>hv</authorinitials>
Documentation/DocBook/media/v4l/vidioc-queryctrl.xml +37 -2
index 0ac0057..02064b0 100644
@@ -215,11 +215,12 @@ the array to zero.</entry>
 
     <table pgwide="1" frame="none" id="v4l2-querymenu">
       <title>struct <structname>v4l2_querymenu</structname></title>
-      <tgroup cols="3">
+      <tgroup cols="4">
 	&cs-str;
 	<tbody valign="top">
 	  <row>
 	    <entry>__u32</entry>
+	    <entry></entry>
 	    <entry><structfield>id</structfield></entry>
 	    <entry>Identifies the control, set by the application
 from the respective &v4l2-queryctrl;
@@ -227,18 +228,38 @@ from the respective &v4l2-queryctrl;
 	  </row>
 	  <row>
 	    <entry>__u32</entry>
+	    <entry></entry>
 	    <entry><structfield>index</structfield></entry>
 	    <entry>Index of the menu item, starting at zero, set by
 	    the application.</entry>
 	  </row>
 	  <row>
+	    <entry>union</entry>
+	    <entry></entry>
+	    <entry></entry>
+	    <entry></entry>
+	  </row>
+	  <row>
+	    <entry></entry>
 	    <entry>__u8</entry>
 	    <entry><structfield>name</structfield>[32]</entry>
 	    <entry>Name of the menu item, a NUL-terminated ASCII
-string. This information is intended for the user.</entry>
+string. This information is intended for the user. This field is valid
+for <constant>V4L2_CTRL_FLAG_MENU</constant> type controls.</entry>
+	  </row>
+	  <row>
+	    <entry></entry>
+	    <entry>__s64</entry>
+	    <entry><structfield>value</structfield></entry>
+	    <entry>
+              Value of the integer menu item. This field is valid for
+              <constant>V4L2_CTRL_FLAG_INTEGER_MENU</constant> type
+              controls.
+            </entry>
 	  </row>
 	  <row>
 	    <entry>__u32</entry>
+	    <entry></entry>
 	    <entry><structfield>reserved</structfield></entry>
 	    <entry>Reserved for future extensions. Drivers must set
 the array to zero.</entry>
@@ -292,6 +313,20 @@ the menu items can be enumerated with the
 <constant>VIDIOC_QUERYMENU</constant> ioctl.</entry>
 	  </row>
 	  <row>
+	    <entry><constant>V4L2_CTRL_TYPE_INTEGER_MENU</constant></entry>
+	    <entry>&ge; 0</entry>
+	    <entry>1</entry>
+	    <entry>N-1</entry>
+	    <entry>
+              The control has a menu of N choices. The values of the
+              menu items can be enumerated with the
+              <constant>VIDIOC_QUERYMENU</constant> ioctl. This is
+              similar to <constant>V4L2_CTRL_TYPE_MENU</constant>
+              except that instead of strings, the menu items are
+              signed 64-bit integers.
+            </entry>
+	  </row>
+	  <row>
 	    <entry><constant>V4L2_CTRL_TYPE_BITMASK</constant></entry>
 	    <entry>0</entry>
 	    <entry>n/a</entry>
Signature · 1 line
1.7.2.5
#5 lore raw

Re: [RFC 02/17] v4l: Document integer menu controls

Hi Sakari,

Thanks for the patch.

Quoted 17 lines · On Tuesday 20 December 2011 21:27:54 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

---
 Documentation/DocBook/media/v4l/compat.xml         |   10 +++++
 Documentation/DocBook/media/v4l/v4l2.xml           |    7 ++++
 .../DocBook/media/v4l/vidioc-queryctrl.xml         |   39

+++++++++++++++++++- 3 files changed, 54 insertions(+), 2 deletions(-)

(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/compat.xml index b68698f..569efd1 100644

Documentation/DocBook/media/v4l/compat.xml +0 -0
@@ -2379,6 +2379,16 @@ that used it. It was originally scheduled for

removal in 2.6.35. </orderedlist>

     </section>

Documentation/DocBook/media/v4l/compat.xml that used it. It was originally scheduled for removal in 2.6.35. · line 2383

Quoted 2 lines
Documentation/DocBook/media/v4l/compat.xml +2 -0
+    <section>
+      <title>V4L2 in Linux 3.3</title>

Seems it will be for 3.4 :-) Same for Documentation/DocBook/media/v4l/v4l2.xml

Quoted 11 lines
Documentation/DocBook/media/v4l/compat.xml +8 -0
+      <orderedlist>
+        <listitem>
+	  <para>Added integer menus, the new type will be
+	  V4L2_CTRL_TYPE_INTEGER_MENU.</para>
+        </listitem>
+      </orderedlist>
+    </section>
+
     <section id="other">
       <title>Relation of V4L2 to other Linux multimedia APIs</title>
Signature · 3 lines
Regards,

Laurent Pinchart
#6 lore raw

Re: [RFC 02/17] v4l: Document integer menu controls

Hi Laurent,

Quoted 22 lines · Laurent Pinchart

Hi Sakari,

Thanks for the patch.

Quoted 17 lines · On Tuesday 20 December 2011 21:27:54 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

---
 Documentation/DocBook/media/v4l/compat.xml         |   10 +++++
 Documentation/DocBook/media/v4l/v4l2.xml           |    7 ++++
 .../DocBook/media/v4l/vidioc-queryctrl.xml         |   39

+++++++++++++++++++- 3 files changed, 54 insertions(+), 2 deletions(-)

(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/compat.xml index b68698f..569efd1 100644

Documentation/DocBook/media/v4l/compat.xml +0 -0
@@ -2379,6 +2379,16 @@ that used it. It was originally scheduled for

removal in 2.6.35. </orderedlist>

     </section>
Quoted 4 lines

Documentation/DocBook/media/v4l/compat.xml that used it. It was originally scheduled for removal in 2.6.35. · line 2383

Quoted 2 lines
Documentation/DocBook/media/v4l/compat.xml +2 -0
+    <section>
+      <title>V4L2 in Linux 3.3</title>

Seems it will be for 3.4 :-) Same for Documentation/DocBook/media/v4l/v4l2.xml

Right. I'll make the change for now but I don't of course mind if we get this to 3.3 already. However, if we want a driver using this go in at the same time, the smia++ driver for almost certain is not going to be 3.3 since it depends on a large set of other patches.

Regards,

Signature · 2 lines
Sakari Ailus
[email protected]
#7 lore raw

RFC 3/17 vivi: Add an integer menu test control

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

Add an integer menu test control for the vivi driver.

---
 drivers/media/video/vivi.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)
drivers/media/video/vivi.c +21 -0
index 7d754fb..763ec23 100644
@@ -177,6 +177,7 @@ struct vivi_dev {
 	struct v4l2_ctrl	   *menu;
 	struct v4l2_ctrl	   *string;
 	struct v4l2_ctrl	   *bitmask;
+	struct v4l2_ctrl	   *int_menu;
 
 	spinlock_t                 slock;
 	struct mutex		   mutex;
@@ -503,6 +504,10 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
 			dev->boolean->cur.val,
 			dev->menu->qmenu[dev->menu->cur.val],
 			dev->string->cur.string);
+	snprintf(str, sizeof(str), " integer_menu %s, value %lld ",
+			dev->int_menu->qmenu[dev->int_menu->cur.val],
+			dev->int64->cur.val64);
+	gen_text(dev, vbuf, line++ * 16, 16, str);
 	mutex_unlock(&dev->ctrl_handler.lock);
 	gen_text(dev, vbuf, line++ * 16, 16, str);
 	if (dev->button_pressed) {
@@ -1183,6 +1188,22 @@ static const struct v4l2_ctrl_config vivi_ctrl_bitmask = {
 	.step = 0,
 };
 
+static const s64 * const vivi_ctrl_int_menu_values[] = {
+	1, 1, 2, 3, 5, 8, 13, 21, 42,
+};
+
+static const struct v4l2_ctrl_config vivi_ctrl_string = {
+	.ops = &vivi_ctrl_ops,
+	.id = VIDI_CID_CUSTOM_BASE + 7
+	.name = "Integer menu",
+	.type = V4L2_CTRL_TYPE_INTEGER_MENU,
+	.min = 1,
+	.max = 8,
+	.def = 4,
+	.menu_skip_mask = 0x02,
+	.qmenu_int = &vivi_ctrl_int_menu_values,
+};
+
 static const struct v4l2_file_operations vivi_fops = {
 	.owner		= THIS_MODULE,
 	.open           = v4l2_fh_open,
Signature · 1 line
1.7.2.5
#8 lore raw

Re: [RFC 03/17] vivi: Add an integer menu test control

Hi Sakari,

Thanks for the patch.

Quoted 22 lines · On Tuesday 20 December 2011 21:27:55 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add an integer menu test control for the vivi driver.

---
 drivers/media/video/vivi.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)
drivers/media/video/vivi.c +1 -0
index 7d754fb..763ec23 100644
@@ -177,6 +177,7 @@ struct vivi_dev {
 	struct v4l2_ctrl	   *menu;
 	struct v4l2_ctrl	   *string;
 	struct v4l2_ctrl	   *bitmask;
+	struct v4l2_ctrl	   *int_menu;
 
 	spinlock_t                 slock;
 	struct mutex		   mutex;

drivers/media/video/vivi.c static void vivi_fillbuff(struct vivi_dev *dev, struct · line 508

Quoted 5 lines
drivers/media/video/vivi.c +2 -0
@@ -503,6 +504,10 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct
 vivi_buffer *buf) dev->boolean->cur.val,
 			dev->menu->qmenu[dev->menu->cur.val],
 			dev->string->cur.string);
+	snprintf(str, sizeof(str), " integer_menu %s, value %lld ",
+			dev->int_menu->qmenu[dev->int_menu->cur.val],

Shouldn't you print the content of qmenu_int as a 64-bit integer instead ?

drivers/media/video/vivi.c static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) · line 509

Quoted 1 line
drivers/media/video/vivi.c +1 -0
+			dev->int64->cur.val64);

Shouldn't this be dev->int_menu->cur.val ?

Quoted 9 lines
drivers/media/video/vivi.c +2 -0
+	gen_text(dev, vbuf, line++ * 16, 16, str);
 	mutex_unlock(&dev->ctrl_handler.lock);
 	gen_text(dev, vbuf, line++ * 16, 16, str);
 	if (dev->button_pressed) {
@@ -1183,6 +1188,22 @@ static const struct v4l2_ctrl_config
 vivi_ctrl_bitmask = { .step = 0,
 };
 
+static const s64 * const vivi_ctrl_int_menu_values[] = {

drivers/media/video/vivi.c static const struct v4l2_ctrl_config · line 1201

Quoted 10 lines
drivers/media/video/vivi.c +10 -0
+	1, 1, 2, 3, 5, 8, 13, 21, 42,
+};
+
+static const struct v4l2_ctrl_config vivi_ctrl_string = {
+	.ops = &vivi_ctrl_ops,
+	.id = VIDI_CID_CUSTOM_BASE + 7
+	.name = "Integer menu",
+	.type = V4L2_CTRL_TYPE_INTEGER_MENU,
+	.min = 1,
+	.max = 8,

There are 9 values in your vivi_ctrl_int_menu_values array. Is 8 on purpose here ?

Quoted 8 lines
drivers/media/video/vivi.c +5 -0
+	.def = 4,
+	.menu_skip_mask = 0x02,
+	.qmenu_int = &vivi_ctrl_int_menu_values,
+};
+
 static const struct v4l2_file_operations vivi_fops = {
 	.owner		= THIS_MODULE,
 	.open           = v4l2_fh_open,
Signature · 3 lines
Regards,

Laurent Pinchart
#9 lore raw

Re: [RFC 03/17] vivi: Add an integer menu test control

Hi Laurent,

Quoted 3 lines · Laurent Pinchart

Hi Sakari,

Thanks for the patch.

Thanks for the review!

Quoted 20 lines · On Tuesday 20 December 2011 21:27:55 Sakari Ailus wrote:
Quoted 19 lines

From: Sakari Ailus <[email protected]>

Add an integer menu test control for the vivi driver.

---
 drivers/media/video/vivi.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)
drivers/media/video/vivi.c +1 -0
index 7d754fb..763ec23 100644
@@ -177,6 +177,7 @@ struct vivi_dev {
 	struct v4l2_ctrl	   *menu;
 	struct v4l2_ctrl	   *string;
 	struct v4l2_ctrl	   *bitmask;
+	struct v4l2_ctrl	   *int_menu;
 
Quoted 10 lines

drivers/media/video/vivi.c static void vivi_fillbuff(struct vivi_dev *dev, struct · line 508

Quoted 8 lines
drivers/media/video/vivi.c +2 -0
 	spinlock_t                 slock;
 	struct mutex		   mutex;
@@ -503,6 +504,10 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct
 vivi_buffer *buf) dev->boolean->cur.val,
 			dev->menu->qmenu[dev->menu->cur.val],
 			dev->string->cur.string);
+	snprintf(str, sizeof(str), " integer_menu %s, value %lld ",
+			dev->int_menu->qmenu[dev->int_menu->cur.val],

Shouldn't you print the content of qmenu_int as a 64-bit integer instead ?

Oh, yes; I should. Also the value would be wrong, as well as the menu item array --- should be the int one.

Quoted 12 lines

drivers/media/video/vivi.c static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) · line 509

Quoted 1 line
drivers/media/video/vivi.c +1 -0
+			dev->int64->cur.val64);

Shouldn't this be dev->int_menu->cur.val ?

Quoted 8 lines
drivers/media/video/vivi.c +1 -0
+	gen_text(dev, vbuf, line++ * 16, 16, str);
 	mutex_unlock(&dev->ctrl_handler.lock);
 	gen_text(dev, vbuf, line++ * 16, 16, str);
 	if (dev->button_pressed) {
@@ -1183,6 +1188,22 @@ static const struct v4l2_ctrl_config
 vivi_ctrl_bitmask = { .step = 0,
 };
 
Quoted 14 lines

drivers/media/video/vivi.c static const struct v4l2_ctrl_config vivi_ctrl_bitmask = { · line 1201

Quoted 11 lines
drivers/media/video/vivi.c +11 -0
+static const s64 * const vivi_ctrl_int_menu_values[] = {
+	1, 1, 2, 3, 5, 8, 13, 21, 42,
+};
+
+static const struct v4l2_ctrl_config vivi_ctrl_string = {
+	.ops = &vivi_ctrl_ops,
+	.id = VIDI_CID_CUSTOM_BASE + 7
+	.name = "Integer menu",
+	.type = V4L2_CTRL_TYPE_INTEGER_MENU,
+	.min = 1,
+	.max = 8,

There are 9 values in your vivi_ctrl_int_menu_values array. Is 8 on purpose here ?

I put it there to limit the maximum to 8 instead of 9, but 9 would be equally good. I'll change it.

Quoted 9 lines
Quoted 8 lines
drivers/media/video/vivi.c +5 -0
+	.def = 4,
+	.menu_skip_mask = 0x02,
+	.qmenu_int = &vivi_ctrl_int_menu_values,
+};
+
 static const struct v4l2_file_operations vivi_fops = {
 	.owner		= THIS_MODULE,
 	.open           = v4l2_fh_open,
Signature · 2 lines
Sakari Ailus
[email protected]
#10 lore raw

Re: [RFC 03/17] vivi: Add an integer menu test control

Sakari Ailus wrote:
...

Quoted 2 lines

I put it there to limit the maximum to 8 instead of 9, but 9 would be equally good. I'll change it.

Or not. 8 is still the index of the last value. min is one to start the menu from the second item. Would you like that to be changed to zero?

Signature · 2 lines
Sakari Ailus
[email protected]
#11 lore raw

Re: [RFC 03/17] vivi: Add an integer menu test control

Hi Sakari,

Quoted 8 lines · On Friday 06 January 2012 11:22:00 Sakari Ailus wrote:

Sakari Ailus wrote:
...

Quoted 2 lines

I put it there to limit the maximum to 8 instead of 9, but 9 would be equally good. I'll change it.

Or not. 8 is still the index of the last value. min is one to start the menu from the second item. Would you like that to be changed to zero?

If it was done on purpose I'm fine with it. I was just pointing it out in case it was done by mistake.

Signature · 3 lines
Regards,

Laurent Pinchart
#12 lore raw

RFC 4/17 v4l: VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

Add support for VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs. They replace functionality provided by VIDIOC_SUBDEV_S_CROP and VIDIOC_SUBDEV_G_CROP IOCTLs and also add new functionality (composing).

VIDIOC_SUBDEV_G_CROP and VIDIOC_SUBDEV_S_CROP continue to be supported.

---
 drivers/media/video/v4l2-subdev.c |   26 ++++++++++++++++++++-
 include/linux/v4l2-subdev.h       |   45 +++++++++++++++++++++++++++++++++++++
 include/media/v4l2-subdev.h       |    5 ++++
 3 files changed, 75 insertions(+), 1 deletions(-)
drivers/media/video/v4l2-subdev.c +25 -1
index 65ade5f..e8ae098 100644
@@ -36,13 +36,17 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
 {
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
 	/* Allocate try format and crop in the same memory block */
-	fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop))
+	fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop)
+			       + sizeof(*fh->try_compose))
 			      * sd->entity.num_pads, GFP_KERNEL);
 	if (fh->try_fmt == NULL)
 		return -ENOMEM;
 
 	fh->try_crop = (struct v4l2_rect *)
 		(fh->try_fmt + sd->entity.num_pads);
+
+	fh->try_compose = (struct v4l2_rect *)
+		(fh->try_crop + sd->entity.num_pads);
 #endif
 	return 0;
 }
@@ -281,6 +285,26 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh,
 					fie);
 	}
+
+	case VIDIOC_SUBDEV_G_SELECTION: {
+		struct v4l2_subdev_selection *sel = arg;
+
+		if (sel->pad >= sd->entity.num_pads)
+			return -EINVAL;
+
+		return v4l2_subdev_call(
+			sd, pad, get_selection, subdev_fh, sel);
+	}
+
+	case VIDIOC_SUBDEV_S_SELECTION: {
+		struct v4l2_subdev_selection *sel = arg;
+
+		if (sel->pad >= sd->entity.num_pads)
+			return -EINVAL;
+
+		return v4l2_subdev_call(
+			sd, pad, set_selection, subdev_fh, sel);
+	}
 #endif
 	default:
 		return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
include/linux/v4l2-subdev.h +45 -0

56 lines not on this page · raw message

include/media/v4l2-subdev.h +5 -0
index f0f3358..26eeaa4 100644
@@ -466,6 +466,10 @@ struct v4l2_subdev_pad_ops {
 		       struct v4l2_subdev_crop *crop);
 	int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
 		       struct v4l2_subdev_crop *crop);
+	int (*get_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+			     struct v4l2_subdev_selection *sel);
+	int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+			     struct v4l2_subdev_selection *sel);
 };
 
 struct v4l2_subdev_ops {
@@ -551,6 +555,7 @@ struct v4l2_subdev_fh {
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
 	struct v4l2_mbus_framefmt *try_fmt;
 	struct v4l2_rect *try_crop;
+	struct v4l2_rect *try_compose;
 #endif
 };
 
Signature · 1 line
1.7.2.5
#13 lore raw

Re: [RFC 04/17] v4l: VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs

Hi Sakari,

Thanks for the patch.

Quoted 7 lines · On Tuesday 20 December 2011 21:27:56 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add support for VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs. They replace functionality provided by VIDIOC_SUBDEV_S_CROP and VIDIOC_SUBDEV_G_CROP IOCTLs and also add new functionality (composing).

VIDIOC_SUBDEV_G_CROP and VIDIOC_SUBDEV_S_CROP continue to be supported.

As those ioctls are experimental, should we deprecate them ?

Quoted 12 lines
---
 drivers/media/video/v4l2-subdev.c |   26 ++++++++++++++++++++-
 include/linux/v4l2-subdev.h       |   45 ++++++++++++++++++++++++++++++++++
 include/media/v4l2-subdev.h       |    5 ++++
 3 files changed, 75 insertions(+), 1 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/v4l2-subdev.c index 65ade5f..e8ae098 100644

drivers/media/video/v4l2-subdev.c static int subdev_fh_init(struct v4l2_subdev_fh *fh, · line 41

Quoted 7 lines
drivers/media/video/v4l2-subdev.c +2 -1
@@ -36,13 +36,17 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh,
 struct v4l2_subdev *sd) {
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
 	/* Allocate try format and crop in the same memory block */
-	fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop))
+	fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop)
+			       + sizeof(*fh->try_compose))
 			      * sd->entity.num_pads, GFP_KERNEL);

Could you check how the 3 structures are aligned on 64-bit platforms ? I'm a bit worried about the compiler expecting a 64-bit alignment for one of them, and getting only a 32-bit alignment in the end.

What about using kcalloc ?

Quoted 12 lines
drivers/media/video/v4l2-subdev.c +3 -0
 	if (fh->try_fmt == NULL)
 		return -ENOMEM;
 
 	fh->try_crop = (struct v4l2_rect *)
 		(fh->try_fmt + sd->entity.num_pads);
+
+	fh->try_compose = (struct v4l2_rect *)
+		(fh->try_crop + sd->entity.num_pads);
 #endif
 	return 0;
 }

drivers/media/video/v4l2-subdev.c static long subdev_do_ioctl(struct file *file, · line 290

Quoted 6 lines
drivers/media/video/v4l2-subdev.c +3 -0
@@ -281,6 +285,26 @@ static long subdev_do_ioctl(struct file *file,
 unsigned int cmd, void *arg) return v4l2_subdev_call(sd, pad,
 enum_frame_interval, subdev_fh, fie);
 	}
+
+	case VIDIOC_SUBDEV_G_SELECTION: {
+		struct v4l2_subdev_selection *sel = arg;

Shouldn't you check sel->which ?

drivers/media/video/v4l2-subdev.c static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) · line 300

Quoted 9 lines
drivers/media/video/v4l2-subdev.c +9 -0
+		if (sel->pad >= sd->entity.num_pads)
+			return -EINVAL;
+
+		return v4l2_subdev_call(
+			sd, pad, get_selection, subdev_fh, sel);
+	}
+
+	case VIDIOC_SUBDEV_S_SELECTION: {
+		struct v4l2_subdev_selection *sel = arg;

And here too ?

Quoted 93 lines
drivers/media/video/v4l2-subdev.c +6 -0
+		if (sel->pad >= sd->entity.num_pads)
+			return -EINVAL;
+
+		return v4l2_subdev_call(
+			sd, pad, set_selection, subdev_fh, sel);
+	}
 #endif
 	default:
 		return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
include/linux/v4l2-subdev.h +27 -0
index ed29cbb..d53d775 100644
@@ -123,6 +123,47 @@ struct v4l2_subdev_frame_interval_enum {
 	__u32 reserved[9];
 };
 
+#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE			(1 << 0)
+#define V4L2_SUBDEV_SEL_FLAG_SIZE_LE			(1 << 1)
+#define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG		(1 << 2)
+
+/* active cropping area */
+#define V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE			0
+/* default cropping area */
+#define V4L2_SUBDEV_SEL_TGT_CROP_DEFAULT		1
+/* cropping bounds */
+#define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS			2
+/* current composing area */
+#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTIVE		256
+/* default composing area */
+#define V4L2_SUBDEV_SEL_TGT_COMPOSE_DEFAULT		257
+/* composing bounds */
+#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS		258
+
+
+/**
+ * struct v4l2_subdev_selection - selection info
+ *
+ * @which: either V4L2_SUBDEV_FORMAT_ACTIVE or V4L2_SUBDEV_FORMAT_TRY
+ * @pad: pad number, as reported by the media API
+ * @target: selection target, used to choose one of possible rectangles
+ * @flags: constraints flags
+ * @r: coordinates of selection window
+ * @reserved: for future use, rounds structure size to 64 bytes, set to

zero + *
+ * Hardware may use multiple helper window to process a video stream.
+ * The structure is used to exchange this selection areas between
+ * an application and a driver.
+ */

include/linux/v4l2-subdev.h +13 -0
+struct v4l2_subdev_selection {
+	__u32 which;
+	__u32 pad;
+	__u32 target;
+	__u32 flags;
+	struct v4l2_rect r;
+	__u32 reserved[8];
+};
+
 #define VIDIOC_SUBDEV_G_FMT	_IOWR('V',  4, struct v4l2_subdev_format)
 #define VIDIOC_SUBDEV_S_FMT	_IOWR('V',  5, struct v4l2_subdev_format)
 #define VIDIOC_SUBDEV_G_FRAME_INTERVAL \
@@ -137,5 +178,9 @@ struct v4l2_subdev_frame_interval_enum {
 			_IOWR('V', 75, struct v4l2_subdev_frame_interval_enum)
 #define VIDIOC_SUBDEV_G_CROP	_IOWR('V', 59, struct v4l2_subdev_crop)
 #define VIDIOC_SUBDEV_S_CROP	_IOWR('V', 60, struct v4l2_subdev_crop)
+#define VIDIOC_SUBDEV_G_SELECTION \
+	_IOWR('V', 61, struct v4l2_subdev_selection)
+#define VIDIOC_SUBDEV_S_SELECTION \
+	_IOWR('V', 62, struct v4l2_subdev_selection)
 
 #endif
include/media/v4l2-subdev.h +5 -0
index f0f3358..26eeaa4 100644
@@ -466,6 +466,10 @@ struct v4l2_subdev_pad_ops {
 		       struct v4l2_subdev_crop *crop);
 	int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
 		       struct v4l2_subdev_crop *crop);
+	int (*get_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+			     struct v4l2_subdev_selection *sel);
+	int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+			     struct v4l2_subdev_selection *sel);
 };
 
 struct v4l2_subdev_ops {
@@ -551,6 +555,7 @@ struct v4l2_subdev_fh {
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
 	struct v4l2_mbus_framefmt *try_fmt;
 	struct v4l2_rect *try_crop;
+	struct v4l2_rect *try_compose;
 #endif
 };
Signature · 3 lines
Regards,

Laurent Pinchart
#14 lore raw

Re: [RFC 04/17] v4l: VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs

Hi Laurent,

Thanks for the comments!

Quoted 10 lines · Laurent Pinchart
Quoted 7 lines · On Tuesday 20 December 2011 21:27:56 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add support for VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs. They replace functionality provided by VIDIOC_SUBDEV_S_CROP and VIDIOC_SUBDEV_G_CROP IOCTLs and also add new functionality (composing).

VIDIOC_SUBDEV_G_CROP and VIDIOC_SUBDEV_S_CROP continue to be supported.

As those ioctls are experimental, should we deprecate them ?

I'm also in favour of doing that. But I'll make it a separate patch.

Quoted 24 lines
Quoted 12 lines
---
 drivers/media/video/v4l2-subdev.c |   26 ++++++++++++++++++++-
 include/linux/v4l2-subdev.h       |   45 ++++++++++++++++++++++++++++++++++
 include/media/v4l2-subdev.h       |    5 ++++
 3 files changed, 75 insertions(+), 1 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/v4l2-subdev.c index 65ade5f..e8ae098 100644

drivers/media/video/v4l2-subdev.c static int subdev_fh_init(struct v4l2_subdev_fh *fh, · line 41

Quoted 7 lines
drivers/media/video/v4l2-subdev.c +2 -1
@@ -36,13 +36,17 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh,
 struct v4l2_subdev *sd) {
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
 	/* Allocate try format and crop in the same memory block */
-	fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop))
+	fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop)
+			       + sizeof(*fh->try_compose))
 			      * sd->entity.num_pads, GFP_KERNEL);

Could you check how the 3 structures are aligned on 64-bit platforms ? I'm a bit worried about the compiler expecting a 64-bit alignment for one of them, and getting only a 32-bit alignment in the end.

Quoted 1 line

What about using kcalloc ?

kcalloc won't make a difference --- see the implementation. Do you think this is really an issue in practice?

If we want to ensure alignment I'd just allocate them separately. Or create a struct out of them locally, and get the pointers from that struct --- then the alignment would be the same as if those were part of a single struct. That achieves the desired result and also keeps error handling trivial.

I wouldn't want to start relying on the alignment based on the sizes of these structures.

Quoted 12 lines
Quoted 12 lines
drivers/media/video/v4l2-subdev.c +3 -0
 	if (fh->try_fmt == NULL)
 		return -ENOMEM;
 
 	fh->try_crop = (struct v4l2_rect *)
 		(fh->try_fmt + sd->entity.num_pads);
+
+	fh->try_compose = (struct v4l2_rect *)
+		(fh->try_crop + sd->entity.num_pads);
 #endif
 	return 0;
 }
@@ -281,6 +285,26 @@ static long subdev_do_ioctl(struct file *file,
Quoted 8 lines

drivers/media/video/v4l2-subdev.c static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) · line 290

Quoted 6 lines
drivers/media/video/v4l2-subdev.c +3 -0
 unsigned int cmd, void *arg) return v4l2_subdev_call(sd, pad,
 enum_frame_interval, subdev_fh, fie);
 	}
+
+	case VIDIOC_SUBDEV_G_SELECTION: {
+		struct v4l2_subdev_selection *sel = arg;

Shouldn't you check sel->which ?

Yes.

Quoted 11 lines

drivers/media/video/v4l2-subdev.c static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg) · line 300

Quoted 9 lines
drivers/media/video/v4l2-subdev.c +9 -0
+		if (sel->pad >= sd->entity.num_pads)
+			return -EINVAL;
+
+		return v4l2_subdev_call(
+			sd, pad, get_selection, subdev_fh, sel);
+	}
+
+	case VIDIOC_SUBDEV_S_SELECTION: {
+		struct v4l2_subdev_selection *sel = arg;

And here too ?

Yes.

Quoted 94 lines
Quoted 93 lines
drivers/media/video/v4l2-subdev.c +6 -0
+		if (sel->pad >= sd->entity.num_pads)
+			return -EINVAL;
+
+		return v4l2_subdev_call(
+			sd, pad, set_selection, subdev_fh, sel);
+	}
 #endif
 	default:
 		return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
include/linux/v4l2-subdev.h +27 -0
index ed29cbb..d53d775 100644
@@ -123,6 +123,47 @@ struct v4l2_subdev_frame_interval_enum {
 	__u32 reserved[9];
 };
 
+#define V4L2_SUBDEV_SEL_FLAG_SIZE_GE			(1 << 0)
+#define V4L2_SUBDEV_SEL_FLAG_SIZE_LE			(1 << 1)
+#define V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG		(1 << 2)
+
+/* active cropping area */
+#define V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE			0
+/* default cropping area */
+#define V4L2_SUBDEV_SEL_TGT_CROP_DEFAULT		1
+/* cropping bounds */
+#define V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS			2
+/* current composing area */
+#define V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTIVE		256
+/* default composing area */
+#define V4L2_SUBDEV_SEL_TGT_COMPOSE_DEFAULT		257
+/* composing bounds */
+#define V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS		258
+
+
+/**
+ * struct v4l2_subdev_selection - selection info
+ *
+ * @which: either V4L2_SUBDEV_FORMAT_ACTIVE or V4L2_SUBDEV_FORMAT_TRY
+ * @pad: pad number, as reported by the media API
+ * @target: selection target, used to choose one of possible rectangles
+ * @flags: constraints flags
+ * @r: coordinates of selection window
+ * @reserved: for future use, rounds structure size to 64 bytes, set to

zero + *
+ * Hardware may use multiple helper window to process a video stream.
+ * The structure is used to exchange this selection areas between
+ * an application and a driver.
+ */

include/linux/v4l2-subdev.h +13 -0
+struct v4l2_subdev_selection {
+	__u32 which;
+	__u32 pad;
+	__u32 target;
+	__u32 flags;
+	struct v4l2_rect r;
+	__u32 reserved[8];
+};
+
 #define VIDIOC_SUBDEV_G_FMT	_IOWR('V',  4, struct v4l2_subdev_format)
 #define VIDIOC_SUBDEV_S_FMT	_IOWR('V',  5, struct v4l2_subdev_format)
 #define VIDIOC_SUBDEV_G_FRAME_INTERVAL \
@@ -137,5 +178,9 @@ struct v4l2_subdev_frame_interval_enum {
 			_IOWR('V', 75, struct v4l2_subdev_frame_interval_enum)
 #define VIDIOC_SUBDEV_G_CROP	_IOWR('V', 59, struct v4l2_subdev_crop)
 #define VIDIOC_SUBDEV_S_CROP	_IOWR('V', 60, struct v4l2_subdev_crop)
+#define VIDIOC_SUBDEV_G_SELECTION \
+	_IOWR('V', 61, struct v4l2_subdev_selection)
+#define VIDIOC_SUBDEV_S_SELECTION \
+	_IOWR('V', 62, struct v4l2_subdev_selection)
 
 #endif
include/media/v4l2-subdev.h +5 -0
index f0f3358..26eeaa4 100644
@@ -466,6 +466,10 @@ struct v4l2_subdev_pad_ops {
 		       struct v4l2_subdev_crop *crop);
 	int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
 		       struct v4l2_subdev_crop *crop);
+	int (*get_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+			     struct v4l2_subdev_selection *sel);
+	int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+			     struct v4l2_subdev_selection *sel);
 };
 
 struct v4l2_subdev_ops {
@@ -551,6 +555,7 @@ struct v4l2_subdev_fh {
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
 	struct v4l2_mbus_framefmt *try_fmt;
 	struct v4l2_rect *try_crop;
+	struct v4l2_rect *try_compose;
 #endif
 };
Signature · 2 lines
Sakari Ailus
[email protected]
#15 lore raw

Re: [RFC 04/17] v4l: VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs

Hi Sakari,

Quoted 44 lines · On Friday 06 January 2012 12:27:03 Sakari Ailus wrote:
Quoted 10 lines · Laurent Pinchart
Quoted 7 lines · On Tuesday 20 December 2011 21:27:56 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add support for VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs. They replace functionality provided by VIDIOC_SUBDEV_S_CROP and VIDIOC_SUBDEV_G_CROP IOCTLs and also add new functionality (composing).

VIDIOC_SUBDEV_G_CROP and VIDIOC_SUBDEV_S_CROP continue to be supported.

As those ioctls are experimental, should we deprecate them ?

I'm also in favour of doing that. But I'll make it a separate patch.

Quoted 30 lines
Quoted 15 lines

---

 drivers/media/video/v4l2-subdev.c |   26 ++++++++++++++++++++-
 include/linux/v4l2-subdev.h       |   45
 ++++++++++++++++++++++++++++++++++ include/media/v4l2-subdev.h       |
    5 ++++
 3 files changed, 75 insertions(+), 1 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/v4l2-subdev.c index 65ade5f..e8ae098 100644

drivers/media/video/v4l2-subdev.c +0 -0
@@ -36,13 +36,17 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh,
 struct v4l2_subdev *sd) {

drivers/media/video/v4l2-subdev.c static int subdev_fh_init(struct v4l2_subdev_fh *fh, · line 45

Quoted 10 lines
drivers/media/video/v4l2-subdev.c +2 -1
 
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
 
 	/* Allocate try format and crop in the same memory block */
 
-	fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop))
+	fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop)
+			       + sizeof(*fh->try_compose))
 
 			      * sd->entity.num_pads, GFP_KERNEL);

Could you check how the 3 structures are aligned on 64-bit platforms ? I'm a bit worried about the compiler expecting a 64-bit alignment for one of them, and getting only a 32-bit alignment in the end.

Quoted 4 lines
Quoted 1 line

What about using kcalloc ?

kcalloc won't make a difference --- see the implementation. Do you think this is really an issue in practice?

It won't make a difference for the alignment, it's just that we allocate an array, so kcalloc seemed right.

Quoted 8 lines

If we want to ensure alignment I'd just allocate them separately. Or create a struct out of them locally, and get the pointers from that struct --- then the alignment would be the same as if those were part of a single struct. That achieves the desired result and also keeps error handling trivial.

I wouldn't want to start relying on the alignment based on the sizes of these structures.

Sounds good to me. Allocating them as part of a bigger structure internally could be more efficient than separate allocations, but I'm fine with both.

Signature · 3 lines
Regards,

Laurent Pinchart
#16 lore raw

Re: [RFC 04/17] v4l: VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs

Hi Laurent,

Quoted 61 lines · Laurent Pinchart

Hi Sakari,

Quoted 44 lines · On Friday 06 January 2012 12:27:03 Sakari Ailus wrote:
Quoted 10 lines · Laurent Pinchart
Quoted 7 lines · On Tuesday 20 December 2011 21:27:56 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add support for VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs. They replace functionality provided by VIDIOC_SUBDEV_S_CROP and VIDIOC_SUBDEV_G_CROP IOCTLs and also add new functionality (composing).

VIDIOC_SUBDEV_G_CROP and VIDIOC_SUBDEV_S_CROP continue to be supported.

As those ioctls are experimental, should we deprecate them ?

I'm also in favour of doing that. But I'll make it a separate patch.

Quoted 30 lines
Quoted 15 lines

---

 drivers/media/video/v4l2-subdev.c |   26 ++++++++++++++++++++-
 include/linux/v4l2-subdev.h       |   45
 ++++++++++++++++++++++++++++++++++ include/media/v4l2-subdev.h       |
    5 ++++
 3 files changed, 75 insertions(+), 1 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/v4l2-subdev.c index 65ade5f..e8ae098 100644

drivers/media/video/v4l2-subdev.c +0 -0
@@ -36,13 +36,17 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh,
 struct v4l2_subdev *sd) {

drivers/media/video/v4l2-subdev.c static int subdev_fh_init(struct v4l2_subdev_fh *fh, · line 45

Quoted 10 lines
drivers/media/video/v4l2-subdev.c +2 -1
 
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
 
 	/* Allocate try format and crop in the same memory block */
 
-	fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop))
+	fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop)
+			       + sizeof(*fh->try_compose))
 
 			      * sd->entity.num_pads, GFP_KERNEL);

Could you check how the 3 structures are aligned on 64-bit platforms ? I'm a bit worried about the compiler expecting a 64-bit alignment for one of them, and getting only a 32-bit alignment in the end.

Quoted 4 lines
Quoted 1 line

What about using kcalloc ?

kcalloc won't make a difference --- see the implementation. Do you think this is really an issue in practice?

It won't make a difference for the alignment, it's just that we allocate an array, so kcalloc seemed right.

Quoted 6 lines

If we want to ensure alignment I'd just allocate them separately. Or create a struct out of them locally, and get the pointers from that struct --- then the alignment would be the same as if those were part of a single struct. That achieves the desired result and also keeps error handling trivial.

Quoted 5 lines
Quoted 2 lines

I wouldn't want to start relying on the alignment based on the sizes of these structures.

Sounds good to me. Allocating them as part of a bigger structure internally could be more efficient than separate allocations, but I'm fine with both.

On second thought, I think I'll combine them into a new anonymous struct the field name of which I call "pad", unless that requires too intrusive changes in other drivers. How about that?

Signature · 2 lines
Sakari Ailus
[email protected]
#17 lore raw

Re: [RFC 04/17] v4l: VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs

Sakari Ailus wrote:
...

Quoted 3 lines

On second thought, I think I'll combine them into a new anonymous struct the field name of which I call "pad", unless that requires too intrusive changes in other drivers. How about that?

And the answer to that is "no". The smia++ driver does store the format, crop and compose values in arrays indexed by pad numbers which I think is a natural thing for the driver to do. In many functiona the driver uses internally it's trivial to choose the array either from driver's internal data structure (V4L2_SUBDEV_FORMAT_ACTIVE) or the file handle (V4L2_SUBDEV_FORMAT_TRY).

Alternatively a named struct could be created for the same, but the drivers might not need all the fields at all, or choose to store them in a different form.

Signature · 2 lines
Sakari Ailus
[email protected]
#18 lore raw

Re: [RFC 04/17] v4l: VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs

Hi Sakari,

Quoted 14 lines · On Saturday 07 January 2012 12:09:29 Sakari Ailus wrote:

Sakari Ailus wrote:
...

Quoted 3 lines

On second thought, I think I'll combine them into a new anonymous struct the field name of which I call "pad", unless that requires too intrusive changes in other drivers. How about that?

And the answer to that is "no". The smia++ driver does store the format, crop and compose values in arrays indexed by pad numbers which I think is a natural thing for the driver to do. In many functiona the driver uses internally it's trivial to choose the array either from driver's internal data structure (V4L2_SUBDEV_FORMAT_ACTIVE) or the file handle (V4L2_SUBDEV_FORMAT_TRY).

Quoted 3 lines

Alternatively a named struct could be created for the same, but the drivers might not need all the fields at all, or choose to store them in a different form.

Drivers should use the v4l2_subdev_get_try_format(), v4l2_subdev_get_try_crop() and v4l2_subdev_get_try_compose() functions to access TRY formats and selection rectangles on file handles, so they shouldn't care about the allocation details.

Signature · 3 lines
Regards,

Laurent Pinchart
#19 lore raw

Re: [RFC 04/17] v4l: VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs

Quoted 17 lines · Laurent Pinchart

Hi Sakari,

Quoted 14 lines · On Saturday 07 January 2012 12:09:29 Sakari Ailus wrote:

Sakari Ailus wrote:
...

Quoted 3 lines

On second thought, I think I'll combine them into a new anonymous struct the field name of which I call "pad", unless that requires too intrusive changes in other drivers. How about that?

And the answer to that is "no". The smia++ driver does store the format, crop and compose values in arrays indexed by pad numbers which I think is a natural thing for the driver to do. In many functiona the driver uses internally it's trivial to choose the array either from driver's internal data structure (V4L2_SUBDEV_FORMAT_ACTIVE) or the file handle (V4L2_SUBDEV_FORMAT_TRY).

Quoted 8 lines
Quoted 3 lines

Alternatively a named struct could be created for the same, but the drivers might not need all the fields at all, or choose to store them in a different form.

Drivers should use the v4l2_subdev_get_try_format(), v4l2_subdev_get_try_crop() and v4l2_subdev_get_try_compose() functions to access TRY formats and selection rectangles on file handles, so they shouldn't care about the allocation details.

Good point... That requires some changes as well, like introduction of v4l2_subdev_get_try_compose(). :-)

Signature · 2 lines
Sakari Ailus
[email protected]
#20 lore raw

RFC 5/17 v4l: Support s_crop and g_crop through s/g_selection

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

Revert to s_selection if s_crop isn't implemented by a driver. Same for g_selection / g_crop.

---
 drivers/media/video/v4l2-subdev.c |   37 +++++++++++++++++++++++++++++++++++--
 1 files changed, 35 insertions(+), 2 deletions(-)
drivers/media/video/v4l2-subdev.c +35 -2
index e8ae098..f8de551 100644
@@ -226,6 +226,8 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 
 	case VIDIOC_SUBDEV_G_CROP: {
 		struct v4l2_subdev_crop *crop = arg;
+		struct v4l2_subdev_selection sel;
+		int rval;
 
 		if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
 		    crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
@@ -234,11 +236,27 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		if (crop->pad >= sd->entity.num_pads)
 			return -EINVAL;
 
-		return v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
+		rval = v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
+		if (rval != -ENOIOCTLCMD)
+			return rval;
+
+		memset(&sel, 0, sizeof(sel));
+		sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+		sel.pad = crop->pad;
+		sel.target = V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE;
+
+		rval = v4l2_subdev_call(
+			sd, pad, get_selection, subdev_fh, &sel);
+
+		crop->rect = sel.r;
+
+		return rval;
 	}
 
 	case VIDIOC_SUBDEV_S_CROP: {
 		struct v4l2_subdev_crop *crop = arg;
+		struct v4l2_subdev_selection sel;
+		int rval;
 
 		if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
 		    crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
@@ -247,7 +265,22 @@ static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 		if (crop->pad >= sd->entity.num_pads)
 			return -EINVAL;
 
-		return v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
+		rval = v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
+		if (rval != -ENOIOCTLCMD)
+			return rval;
+
+		memset(&sel, 0, sizeof(sel));
+		sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+		sel.pad = crop->pad;
+		sel.target = V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE;
+		sel.r = crop->rect;
+
+		rval = v4l2_subdev_call(
+			sd, pad, set_selection, subdev_fh, &sel);
+
+		crop->rect = sel.r;
+
+		return rval;
 	}
 
 	case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {
Signature · 1 line
1.7.2.5
#21 lore raw

Re: [RFC 05/17] v4l: Support s_crop and g_crop through s/g_selection

Hi Sakari,

Thanks for the patch.

Quoted 4 lines · On Tuesday 20 December 2011 21:27:57 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Revert to s_selection if s_crop isn't implemented by a driver. Same for g_selection / g_crop.

Shouldn't this say "Fall back" instead of "Revert" ?

Quoted 21 lines
---
 drivers/media/video/v4l2-subdev.c |   37

+++++++++++++++++++++++++++++++++++-- 1 files changed, 35 insertions(+), 2 deletions(-)

(quoted diff) +0 -0

b/drivers/media/video/v4l2-subdev.c index e8ae098..f8de551 100644

drivers/media/video/v4l2-subdev.c +2 -0
@@ -226,6 +226,8 @@ static long subdev_do_ioctl(struct file *file, unsigned
 int cmd, void *arg)
 
 	case VIDIOC_SUBDEV_G_CROP: {
 		struct v4l2_subdev_crop *crop = arg;
+		struct v4l2_subdev_selection sel;
+		int rval;
 
 		if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
drivers/media/video/v4l2-subdev.c +0 -0
 		    crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)

drivers/media/video/v4l2-subdev.c static long subdev_do_ioctl(struct file *file, · line 244

Quoted 10 lines
drivers/media/video/v4l2-subdev.c +6 -1
@@ -234,11 +236,27 @@ static long subdev_do_ioctl(struct file *file,
 unsigned int cmd, void *arg) if (crop->pad >= sd->entity.num_pads)
 			return -EINVAL;
 
-		return v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
+		rval = v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
+		if (rval != -ENOIOCTLCMD)
+			return rval;
+
+		memset(&sel, 0, sizeof(sel));
+		sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;

Shouldn't sel.which be set to crop->which ?

Quoted 19 lines
drivers/media/video/v4l2-subdev.c +11 -0
+		sel.pad = crop->pad;
+		sel.target = V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE;
+
+		rval = v4l2_subdev_call(
+			sd, pad, get_selection, subdev_fh, &sel);
+
+		crop->rect = sel.r;
+
+		return rval;
 	}
 
 	case VIDIOC_SUBDEV_S_CROP: {
 		struct v4l2_subdev_crop *crop = arg;
+		struct v4l2_subdev_selection sel;
+		int rval;
 
 		if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
 		    crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)

drivers/media/video/v4l2-subdev.c static long subdev_do_ioctl(struct file *file, · line 273

Quoted 10 lines
drivers/media/video/v4l2-subdev.c +6 -1
@@ -247,7 +265,22 @@ static long subdev_do_ioctl(struct file *file,
 unsigned int cmd, void *arg) if (crop->pad >= sd->entity.num_pads)
 			return -EINVAL;
 
-		return v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
+		rval = v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
+		if (rval != -ENOIOCTLCMD)
+			return rval;
+
+		memset(&sel, 0, sizeof(sel));
+		sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;

Same here.

Quoted 13 lines
drivers/media/video/v4l2-subdev.c +10 -0
+		sel.pad = crop->pad;
+		sel.target = V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE;
+		sel.r = crop->rect;
+
+		rval = v4l2_subdev_call(
+			sd, pad, set_selection, subdev_fh, &sel);
+
+		crop->rect = sel.r;
+
+		return rval;
 	}
 
 	case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {
Signature · 3 lines
Regards,

Laurent Pinchart
#22 lore raw

Re: [RFC 05/17] v4l: Support s_crop and g_crop through s/g_selection

Hi Laurent,

Quoted 11 lines · Laurent Pinchart

Hi Sakari,

Thanks for the patch.

Quoted 4 lines · On Tuesday 20 December 2011 21:27:57 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Revert to s_selection if s_crop isn't implemented by a driver. Same for g_selection / g_crop.

Shouldn't this say "Fall back" instead of "Revert" ?

Fixed all issues you mentioned in this e-mail.

Quoted 80 lines
Quoted 21 lines
---
 drivers/media/video/v4l2-subdev.c |   37

+++++++++++++++++++++++++++++++++++-- 1 files changed, 35 insertions(+), 2 deletions(-)

(quoted diff) +0 -0

b/drivers/media/video/v4l2-subdev.c index e8ae098..f8de551 100644

drivers/media/video/v4l2-subdev.c +2 -0
@@ -226,6 +226,8 @@ static long subdev_do_ioctl(struct file *file, unsigned
 int cmd, void *arg)
 
 	case VIDIOC_SUBDEV_G_CROP: {
 		struct v4l2_subdev_crop *crop = arg;
+		struct v4l2_subdev_selection sel;
+		int rval;
 
 		if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
drivers/media/video/v4l2-subdev.c +0 -0
 		    crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)

drivers/media/video/v4l2-subdev.c static long subdev_do_ioctl(struct file *file, · line 244

Quoted 10 lines
drivers/media/video/v4l2-subdev.c +6 -1
@@ -234,11 +236,27 @@ static long subdev_do_ioctl(struct file *file,
 unsigned int cmd, void *arg) if (crop->pad >= sd->entity.num_pads)
 			return -EINVAL;
 
-		return v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
+		rval = v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
+		if (rval != -ENOIOCTLCMD)
+			return rval;
+
+		memset(&sel, 0, sizeof(sel));
+		sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;

Shouldn't sel.which be set to crop->which ?

Quoted 19 lines
drivers/media/video/v4l2-subdev.c +11 -0
+		sel.pad = crop->pad;
+		sel.target = V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE;
+
+		rval = v4l2_subdev_call(
+			sd, pad, get_selection, subdev_fh, &sel);
+
+		crop->rect = sel.r;
+
+		return rval;
 	}
 
 	case VIDIOC_SUBDEV_S_CROP: {
 		struct v4l2_subdev_crop *crop = arg;
+		struct v4l2_subdev_selection sel;
+		int rval;
 
 		if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
 		    crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)

drivers/media/video/v4l2-subdev.c static long subdev_do_ioctl(struct file *file, · line 273

Quoted 10 lines
drivers/media/video/v4l2-subdev.c +6 -1
@@ -247,7 +265,22 @@ static long subdev_do_ioctl(struct file *file,
 unsigned int cmd, void *arg) if (crop->pad >= sd->entity.num_pads)
 			return -EINVAL;
 
-		return v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
+		rval = v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
+		if (rval != -ENOIOCTLCMD)
+			return rval;
+
+		memset(&sel, 0, sizeof(sel));
+		sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;

Same here.

Quoted 13 lines
drivers/media/video/v4l2-subdev.c +10 -0
+		sel.pad = crop->pad;
+		sel.target = V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE;
+		sel.r = crop->rect;
+
+		rval = v4l2_subdev_call(
+			sd, pad, set_selection, subdev_fh, &sel);
+
+		crop->rect = sel.r;
+
+		return rval;
 	}
 
 	case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {
Signature · 2 lines
Sakari Ailus
[email protected]
#23 lore raw

RFC 6/17 v4l: Add selections documentation.

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

---
 Documentation/DocBook/media/v4l/dev-subdev.xml     |   95 +++++++--
 Documentation/DocBook/media/v4l/v4l2.xml           |    1 +
 .../media/v4l/vidioc-subdev-g-selection.xml        |  226 ++++++++++++++++++++
 3 files changed, 302 insertions(+), 20 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
Documentation/DocBook/media/v4l/dev-subdev.xml +75 -20
index 0916a73..722db60 100644
@@ -77,7 +77,7 @@
     format, frame width and frame height.</para></note>
 
     <para>Image formats are typically negotiated on video capture and output
-    devices using the <link linkend="crop">cropping and scaling</link> ioctls.
+    devices using the format and <link linkend="selection">selection</link> ioctls.
     The driver is responsible for configuring every block in the video pipeline
     according to the requested format at the pipeline input and/or
     output.</para>
@@ -276,11 +276,11 @@
     </section>
 
     <section>
-      <title>Cropping and scaling</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
-      interest in an image, typically on a video sensor or video decoder. It can
+      interest in an image, typically on an image sensor or a video decoder. It can
       also be used as part of digital zoom implementations to select the area of
       the image that will be scaled up.</para>
 
@@ -288,26 +288,81 @@
       &v4l2-rect; by the coordinates of the top left corner and the rectangle
       size. Both the coordinates and sizes are expressed in pixels.</para>
 
-      <para>The crop rectangle is retrieved and set using the
-      &VIDIOC-SUBDEV-G-CROP; and &VIDIOC-SUBDEV-S-CROP; ioctls. Like for pad
-      formats, drivers store try and active crop rectangles. The format
-      negotiation mechanism applies to crop settings as well.</para>
-
-      <para>On input pads, cropping is applied relatively to the current pad
-      format. The pad format represents the image size as received by the
-      sub-device from the previous block in the pipeline, and the crop rectangle
-      represents the sub-image that will be transmitted further inside the
-      sub-device for processing. The crop rectangle be entirely containted
-      inside the input image size.</para>
-
-      <para>Input crop rectangle are reset to their default value when the input
-      image format is modified. Drivers should use the input image size as the
-      crop rectangle default value, but hardware requirements may prevent this.
-      </para>
+      <para>Scaling operation changes the size of the image by scaling
+      it to new dimensions. Some sub-devices support it. The scaled
+      size (width and height) is represented by &v4l2-rect;. In the
+      case of scaling, top and left will always be zero. Scaling is
+      configured using &sub-subdev-g-selection; and
+      <constant>V4L2_SUBDEV_SEL_COMPOSE_ACTIVE</constant> selection
+      target on the sink pad of the subdev. The scaling is performed
+      related to the width and height of the crop rectangle on the
+      subdev's sink pad.</para>
+
+      <para>As for pad formats, drivers store try and active
+      rectangles for the selection targets of ACTIVE type <xref
+      linkend="v4l2-subdev-selection-targets">.</xref></para>
+
+      <para>On sink pads, cropping is applied relatively to the
+      current pad format. The pad format represents the image size as
+      received by the sub-device from the previous block in the
+      pipeline, and the crop rectangle represents the sub-image that
+      will be transmitted further inside the sub-device for
+      processing.</para>
+
+      <para>On source pads, cropping is similar to sink pads, with the
+      exception that the source size from which the cropping is
+      performed, is the COMPOSE rectangle on the sink pad. In both
+      sink and source pads, the crop rectangle must be entirely
+      containted inside the source image size for the crop
+      operation.</para>
+
+      <para>The drivers should always use the closest possible
+      rectangle the user requests on all selection targets, unless
+      specificly told otherwise<xref
+      linkend="v4l2-subdev-selection-flags">.</xref></para>
+    </section>
+
+    <section>
+      <title>Order of configuration and format propagation</title>
+
+      <para>The order of image processing steps will always be from
+      the sink pad towards the source pad. This is also reflected in
+      the order in which the configuration must be performed by the
+      user. The format is propagated within the subdev along the later
+      processing steps. For example, setting the sink pad format
+      causes all the selection rectangles and the source pad format to
+      be set to sink pad format --- if allowed by the hardware, and if
+      not, then closest possible. The coordinates to a step always
+      refer to the active size of the previous step.</para>
+
+      <orderedlist>
+	<listitem>Sink pad format. The user configures the sink pad
+	format. This format defines the parameters of the image the
+	entity receives through the pad for further processing.</listitem>
 
-      <para>Cropping behaviour on output pads is not defined.</para>
+	<listitem>Sink pad active crop selection. The sink pad crop
+	defines the performed to the sink pad format.</listitem>
 
+	<listitem>Sink pad active compose selection. The sink pad compose
+	rectangle defines the scaling ratio compared to the size of
+	the sink pad crop rectangle.</listitem>
+
+	<listitem>Source pad active crop selection. Crop on the source
+	pad defines crop performed to the image scaled according to
+	the sink pad compose rectangle.</listitem>
+
+	<listitem>Source pad active compose selection. The source pad
+	compose defines the size and location of the compose
+	rectangle.</listitem>
+
+	<listitem>Source pad format. The source pad format defines the
+	output pixel format of the subdev, as well as the other
+	parameters with the exception of the image width and
+	height.</listitem>
+
+      </orderedlist>
     </section>
+
   </section>
 
   &sub-subdev-formats;
Documentation/DocBook/media/v4l/v4l2.xml +1 -0
index affe1ba..3ff11a6 100644
@@ -529,6 +529,7 @@ and discussions on the V4L mailing list.</revremark>
     &sub-subdev-g-crop;
     &sub-subdev-g-fmt;
     &sub-subdev-g-frame-interval;
+    &sub-subdev-g-selection;
     &sub-subscribe-event;
     <!-- End of ioctls. -->
     &sub-mmap;
Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +226 -0

226 lines not on this page · raw message

Signature · 1 line
1.7.2.5
#24 lore raw

Re: [RFC 06/17] v4l: Add selections documentation.

Hi Sakari,

Thanks for the patch.

On Tuesday 20 December 2011 21:27:58 Sakari Ailus wrote:

[snip]

Quoted 5 lines
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/dev-subdev.xml index 0916a73..722db60 100644

Documentation/DocBook/media/v4l/dev-subdev.xml +0 -0

[snip]

Quoted 1 line
Documentation/DocBook/media/v4l/dev-subdev.xml +0 -0
@@ -288,26 +288,81 @@

[snip]

Quoted 23 lines
Documentation/DocBook/media/v4l/dev-subdev.xml +23 -0
+      <para>Scaling operation changes the size of the image by scaling
+      it to new dimensions. Some sub-devices support it. The scaled
+      size (width and height) is represented by &v4l2-rect;. In the
+      case of scaling, top and left will always be zero. Scaling is
+      configured using &sub-subdev-g-selection; and
+      <constant>V4L2_SUBDEV_SEL_COMPOSE_ACTIVE</constant> selection
+      target on the sink pad of the subdev. The scaling is performed
+      related to the width and height of the crop rectangle on the
+      subdev's sink pad.</para>
+
+      <para>As for pad formats, drivers store try and active
+      rectangles for the selection targets of ACTIVE type <xref
+      linkend="v4l2-subdev-selection-targets">.</xref></para>
+
+      <para>On sink pads, cropping is applied relatively to the
+      current pad format. The pad format represents the image size as
+      received by the sub-device from the previous block in the
+      pipeline, and the crop rectangle represents the sub-image that
+      will be transmitted further inside the sub-device for
+      processing.</para>
+
+      <para>On source pads, cropping is similar to sink pads, with the
+      exception that the source size from which the cropping is

Documentation/DocBook/media/v4l/dev-subdev.xml line 323

Quoted 10 lines
Documentation/DocBook/media/v4l/dev-subdev.xml +10 -0
+      performed, is the COMPOSE rectangle on the sink pad. In both
+      sink and source pads, the crop rectangle must be entirely
+      containted inside the source image size for the crop
+      operation.</para>
+
+      <para>The drivers should always use the closest possible
+      rectangle the user requests on all selection targets, unless
+      specificly told otherwise<xref
+      linkend="v4l2-subdev-selection-flags">.</xref></para>
+    </section>

This sounds a bit confusing to me. One issue is that composing is not formally defined. I think it would help if you could draw a diagram that shows how the operations are applied, and modify the text to describe the diagram, using the natural order of the compose and crop operations on sink and source pads.

Documentation/DocBook/media/v4l/dev-subdev.xml line 336

Quoted 12 lines
Documentation/DocBook/media/v4l/dev-subdev.xml +12 -0
+    <section>
+      <title>Order of configuration and format propagation</title>
+
+      <para>The order of image processing steps will always be from
+      the sink pad towards the source pad. This is also reflected in
+      the order in which the configuration must be performed by the
+      user. The format is propagated within the subdev along the later
+      processing steps. For example, setting the sink pad format
+      causes all the selection rectangles and the source pad format to
+      be set to sink pad format --- if allowed by the hardware, and if
+      not, then closest possible. The coordinates to a step always
+      refer to the active size of the previous step.</para>

This also sounds a bit ambiguous if I try to ignore the fact that I know how it works :-) You should at least make it explicit that propagation inside subdevs is performed by the driver(s), and that propagation outside subdevs is to be handled by userspace.

Quoted 32 lines
Documentation/DocBook/media/v4l/dev-subdev.xml +25 -1
+      <orderedlist>
+	<listitem>Sink pad format. The user configures the sink pad
+	format. This format defines the parameters of the image the
+	entity receives through the pad for further processing.</listitem>
 
-      <para>Cropping behaviour on output pads is not defined.</para>
+	<listitem>Sink pad active crop selection. The sink pad crop
+	defines the performed to the sink pad format.</listitem>
 
+	<listitem>Sink pad active compose selection. The sink pad compose
+	rectangle defines the scaling ratio compared to the size of
+	the sink pad crop rectangle.</listitem>
+
+	<listitem>Source pad active crop selection. Crop on the source
+	pad defines crop performed to the image scaled according to
+	the sink pad compose rectangle.</listitem>
+
+	<listitem>Source pad active compose selection. The source pad
+	compose defines the size and location of the compose
+	rectangle.</listitem>
+
+	<listitem>Source pad format. The source pad format defines the
+	output pixel format of the subdev, as well as the other
+	parameters with the exception of the image width and
+	height.</listitem>
+
+      </orderedlist>
     </section>
+
   </section>
 
   &sub-subdev-formats;

[snip]

Quoted 7 lines
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file mode 100644
index 0000000..5fbcd65

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +0 -0
@@ -0,0 +1,226 @@

[snip]

Quoted 20 lines
Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +20 -0
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+      <para>This is an <link linkend="experimental">experimental</link>
+      interface and may change in the future.</para>
+    </note>
+
+    <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>
+
+    <para>The selections replace the crop API &sub-subdev-g-crop;. All
+    the function of the crop API, and more, are supported by the
+    selections API.</para>
+
+    <para>See <xref linkend="subdev">Sub-device interface</xref> for
+    more information on how each selection target affects the image

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml

Quoted 10 lines
Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +10 -0
+    processing pipeline inside the subdevice.</para>
+
+    <section>
+      <title>Types of selection targets</title>
+
+      <para>The are four types of selection targets: active, default,
+      bounds and padding. The ACTIVE targets are the targets which
+      configure the hardware. The DEFAULT target provides the default
+      for the ACTIVE selection. The BOUNDS target will return the
+      maximum width and height of the target.

What about the minimum ?

Quoted 2 lines

The PADDED target
+ provides the width and height for the padded image,

Is it valid for both crop and compose rectangles ?

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml line 81

Quoted 3 lines

and is

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +2 -0
+      directly affected by the ACTIVE target. The PADDED targets may
+      be configurable depending on the hardware.</para>

If that's configurable drivers will need a way to store it in the file handle.

Quoted 148 lines
Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +25 -0
+    </section>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-selection-targets">
+      <title>V4L2 subdev selection targets</title>
+      <tgroup cols="3">
+        &cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE</constant></entry>
+	    <entry>0</entry>
+	    <entry>Active crop. Defines the cropping
+	    performed by the processing step.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_TGT_CROP_DEFAULT</constant></entry>
+	    <entry>1</entry>
+	    <entry>Default crop rectangle.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS</constant></entry>
+	    <entry>2</entry>
+	    <entry>Bounds of the crop rectangle.</entry>
+	  </row>
+	  <row>
+	   

<entry><constant>V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTIVE</constant></entry> +
<entry>256</entry>

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +5 -0
+	    <entry>Active compose rectangle. Used to configure scaling
+	    on sink pads and composition on source pads.</entry>
+	  </row>
+	  <row>
+	   

<entry><constant>V4L2_SUBDEV_SEL_TGT_COMPOSE_DEFAULT</constant></entry> +
<entry>257</entry>

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +4 -0
+	    <entry>Default compose rectangle.</entry>
+	  </row>
+	  <row>
+	   

<entry><constant>V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS</constant></entry> +
<entry>258</entry>

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +108 -0
+	    <entry>Bounds of the compose rectangle.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-selection-flags">
+      <title>V4L2 subdev selection flags</title>
+      <tgroup cols="3">
+        &cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_FLAG_SIZE_GE</constant></entry>
+	    <entry>(1 &lt;&lt; 0)</entry>
+	    <entry>Suggest the driver it should choose greater or
+	    equal rectangle (in size) than was requested.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_FLAG_SIZE_LE</constant></entry>
+	    <entry>(1 &lt;&lt; 1)</entry>
+	    <entry>Suggest the driver it should choose lesser or
+	    equal rectangle (in size) than was requested.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG</constant></entry>
+	    <entry>(1 &lt;&lt; 2)</entry>
+	    <entry>The configuration should not be propagated to any
+	    further processing steps. If this flag is not given, the
+	    configuration is propagated inside the subdevice to all
+	    further processing steps.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-selection">
+      <title>struct <structname>v4l2_subdev_selection</structname></title>
+      <tgroup cols="3">
+        &cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>which</structfield></entry>
+	    <entry>Active or try selection, from
+	    &v4l2-subdev-format-whence;.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>pad</structfield></entry>
+	    <entry>Pad number as reported by the media framework.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>target</structfield></entry>
+	    <entry>Target selection rectangle. See
+	    <xref linkend="v4l2-subdev-selection-targets">.</xref>.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>flags</structfield></entry>
+	    <entry>Flags. See
+	    <xref linkend="v4l2-subdev-selection-flags">.</xref></entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-rect;</entry>
+	    <entry><structfield>rect</structfield></entry>
+	    <entry>Crop rectangle boundaries, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
+	    <entry>Reserved for future extensions. Applications and drivers must
+	    set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The selection rectangle can't be changed because the
+	  pad is currently busy. This can be caused, for instance, by
+	  an active video stream on the pad. The ioctl must not be
+	  retried without performing another action to fix the problem
+	  first. Only returned by
+	  <constant>VIDIOC_SUBDEV_S_SELECTION</constant></para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-subdev-selection;
+	  <structfield>pad</structfield> references a non-existing
+	  pad, the <structfield>which</structfield> field references a
+	  non-existing format, or the selection target is not
+	  supported on the given subdev pad.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
Signature · 3 lines
Regards,

Laurent Pinchart
#25 lore raw

Re: [RFC 06/17] v4l: Add selections documentation.

Hi Laurent,

Thanks for the comments!

Quoted 46 lines · Laurent Pinchart

On Tuesday 20 December 2011 21:27:58 Sakari Ailus wrote:

[snip]

Quoted 5 lines
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/dev-subdev.xml index 0916a73..722db60 100644

Documentation/DocBook/media/v4l/dev-subdev.xml +0 -0

[snip]

Quoted 1 line
Documentation/DocBook/media/v4l/dev-subdev.xml +0 -0
@@ -288,26 +288,81 @@

[snip]

Quoted 30 lines
Documentation/DocBook/media/v4l/dev-subdev.xml +30 -0
+      <para>Scaling operation changes the size of the image by scaling
+      it to new dimensions. Some sub-devices support it. The scaled
+      size (width and height) is represented by &v4l2-rect;. In the
+      case of scaling, top and left will always be zero. Scaling is
+      configured using &sub-subdev-g-selection; and
+      <constant>V4L2_SUBDEV_SEL_COMPOSE_ACTIVE</constant> selection
+      target on the sink pad of the subdev. The scaling is performed
+      related to the width and height of the crop rectangle on the
+      subdev's sink pad.</para>
+
+      <para>As for pad formats, drivers store try and active
+      rectangles for the selection targets of ACTIVE type <xref
+      linkend="v4l2-subdev-selection-targets">.</xref></para>
+
+      <para>On sink pads, cropping is applied relatively to the
+      current pad format. The pad format represents the image size as
+      received by the sub-device from the previous block in the
+      pipeline, and the crop rectangle represents the sub-image that
+      will be transmitted further inside the sub-device for
+      processing.</para>
+
+      <para>On source pads, cropping is similar to sink pads, with the
+      exception that the source size from which the cropping is
+      performed, is the COMPOSE rectangle on the sink pad. In both
+      sink and source pads, the crop rectangle must be entirely
+      containted inside the source image size for the crop
+      operation.</para>
+
+      <para>The drivers should always use the closest possible
+      rectangle the user requests on all selection targets, unless
Quoted 8 lines

Documentation/DocBook/media/v4l/dev-subdev.xml line 323

Quoted 3 lines
Documentation/DocBook/media/v4l/dev-subdev.xml +3 -0
+      specificly told otherwise<xref
+      linkend="v4l2-subdev-selection-flags">.</xref></para>
+    </section>

This sounds a bit confusing to me. One issue is that composing is not formally defined. I think it would help if you could draw a diagram that shows how the operations are applied, and modify the text to describe the diagram, using the natural order of the compose and crop operations on sink and source pads.

I drew a diagram based on your suggestion, but I'd prefer the formal definition would come from someone who needs composition and better understands the use cases.

Also cc Tomasz.

Quoted 13 lines

Documentation/DocBook/media/v4l/dev-subdev.xml line 336

Quoted 12 lines
Documentation/DocBook/media/v4l/dev-subdev.xml +12 -0
+    <section>
+      <title>Order of configuration and format propagation</title>
+
+      <para>The order of image processing steps will always be from
+      the sink pad towards the source pad. This is also reflected in
+      the order in which the configuration must be performed by the
+      user. The format is propagated within the subdev along the later
+      processing steps. For example, setting the sink pad format
+      causes all the selection rectangles and the source pad format to
+      be set to sink pad format --- if allowed by the hardware, and if
+      not, then closest possible. The coordinates to a step always
+      refer to the active size of the previous step.</para>
Quoted 4 lines

This also sounds a bit ambiguous if I try to ignore the fact that I know how it works :-) You should at least make it explicit that propagation inside subdevs is performed by the driver(s), and that propagation outside subdevs is to be handled by userspace.

Agreed. I'll reword it.

Quoted 69 lines
Quoted 32 lines
Documentation/DocBook/media/v4l/dev-subdev.xml +25 -1
+      <orderedlist>
+	<listitem>Sink pad format. The user configures the sink pad
+	format. This format defines the parameters of the image the
+	entity receives through the pad for further processing.</listitem>
 
-      <para>Cropping behaviour on output pads is not defined.</para>
+	<listitem>Sink pad active crop selection. The sink pad crop
+	defines the performed to the sink pad format.</listitem>
 
+	<listitem>Sink pad active compose selection. The sink pad compose
+	rectangle defines the scaling ratio compared to the size of
+	the sink pad crop rectangle.</listitem>
+
+	<listitem>Source pad active crop selection. Crop on the source
+	pad defines crop performed to the image scaled according to
+	the sink pad compose rectangle.</listitem>
+
+	<listitem>Source pad active compose selection. The source pad
+	compose defines the size and location of the compose
+	rectangle.</listitem>
+
+	<listitem>Source pad format. The source pad format defines the
+	output pixel format of the subdev, as well as the other
+	parameters with the exception of the image width and
+	height.</listitem>
+
+      </orderedlist>
     </section>
+
   </section>
 
   &sub-subdev-formats;

[snip]

Quoted 7 lines
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file mode 100644
index 0000000..5fbcd65

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +0 -0
@@ -0,0 +1,226 @@

[snip]

Quoted 24 lines
Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +24 -0
+  <refsect1>
+    <title>Description</title>
+
+    <note>
+      <title>Experimental</title>
+      <para>This is an <link linkend="experimental">experimental</link>
+      interface and may change in the future.</para>
+    </note>
+
+    <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>
+
+    <para>The selections replace the crop API &sub-subdev-g-crop;. All
+    the function of the crop API, and more, are supported by the
+    selections API.</para>
+
+    <para>See <xref linkend="subdev">Sub-device interface</xref> for
+    more information on how each selection target affects the image
+    processing pipeline inside the subdevice.</para>
+
+    <section>
+      <title>Types of selection targets</title>
Quoted 8 lines

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml

Quoted 6 lines
Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +6 -0
+
+      <para>The are four types of selection targets: active, default,
+      bounds and padding. The ACTIVE targets are the targets which
+      configure the hardware. The DEFAULT target provides the default
+      for the ACTIVE selection. The BOUNDS target will return the
+      maximum width and height of the target.

What about the minimum ?

Good question. We could also specify that the minimum is obtained by using the V4L2_SUBDEV_SEL_FLAG_LE flag with the BOUNDS target.

Quoted 4 lines
Quoted 2 lines

The PADDED target
+ provides the width and height for the padded image,

Is it valid for both crop and compose rectangles ?

I think all targets are valid for all rectangles. Should I mention that?

The practical use cases may be more limited, though. I wonder if I should remove the padded targets until we get use cases for them. I included them for the reason that they also exist in the V4L2.

Tomasz, Sylwester: do you have use for the PADDED targets?

I think we also must define what will be done in cases where crop (on either sink or source) / scaling / composition is not supported by the subdev. That's currently undefined. I think it'd be most clear to return an error code but I'm not sure which one --- EINVAL is an obvious candidate but that is also returned when the pad is wrong. It looks still like the best choice to me.

Quoted 5 lines

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml line 81

Quoted 3 lines

and is

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +2 -0
+      directly affected by the ACTIVE target. The PADDED targets may
+      be configurable depending on the hardware.</para>

If that's configurable drivers will need a way to store it in the file handle.

Good point. I'll add it if we end up defining the padded targets now.

Quoted 149 lines
Quoted 148 lines
Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +25 -0
+    </section>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-selection-targets">
+      <title>V4L2 subdev selection targets</title>
+      <tgroup cols="3">
+        &cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE</constant></entry>
+	    <entry>0</entry>
+	    <entry>Active crop. Defines the cropping
+	    performed by the processing step.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_TGT_CROP_DEFAULT</constant></entry>
+	    <entry>1</entry>
+	    <entry>Default crop rectangle.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS</constant></entry>
+	    <entry>2</entry>
+	    <entry>Bounds of the crop rectangle.</entry>
+	  </row>
+	  <row>
+	   

<entry><constant>V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTIVE</constant></entry> +
<entry>256</entry>

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +5 -0
+	    <entry>Active compose rectangle. Used to configure scaling
+	    on sink pads and composition on source pads.</entry>
+	  </row>
+	  <row>
+	   

<entry><constant>V4L2_SUBDEV_SEL_TGT_COMPOSE_DEFAULT</constant></entry> +
<entry>257</entry>

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +4 -0
+	    <entry>Default compose rectangle.</entry>
+	  </row>
+	  <row>
+	   

<entry><constant>V4L2_SUBDEV_SEL_TGT_COMPOSE_BOUNDS</constant></entry> +
<entry>258</entry>

Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +108 -0
+	    <entry>Bounds of the compose rectangle.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-selection-flags">
+      <title>V4L2 subdev selection flags</title>
+      <tgroup cols="3">
+        &cs-def;
+	<tbody valign="top">
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_FLAG_SIZE_GE</constant></entry>
+	    <entry>(1 &lt;&lt; 0)</entry>
+	    <entry>Suggest the driver it should choose greater or
+	    equal rectangle (in size) than was requested.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_FLAG_SIZE_LE</constant></entry>
+	    <entry>(1 &lt;&lt; 1)</entry>
+	    <entry>Suggest the driver it should choose lesser or
+	    equal rectangle (in size) than was requested.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG</constant></entry>
+	    <entry>(1 &lt;&lt; 2)</entry>
+	    <entry>The configuration should not be propagated to any
+	    further processing steps. If this flag is not given, the
+	    configuration is propagated inside the subdevice to all
+	    further processing steps.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+    <table pgwide="1" frame="none" id="v4l2-subdev-selection">
+      <title>struct <structname>v4l2_subdev_selection</structname></title>
+      <tgroup cols="3">
+        &cs-str;
+	<tbody valign="top">
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>which</structfield></entry>
+	    <entry>Active or try selection, from
+	    &v4l2-subdev-format-whence;.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>pad</structfield></entry>
+	    <entry>Pad number as reported by the media framework.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>target</structfield></entry>
+	    <entry>Target selection rectangle. See
+	    <xref linkend="v4l2-subdev-selection-targets">.</xref>.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>flags</structfield></entry>
+	    <entry>Flags. See
+	    <xref linkend="v4l2-subdev-selection-flags">.</xref></entry>
+	  </row>
+	  <row>
+	    <entry>&v4l2-rect;</entry>
+	    <entry><structfield>rect</structfield></entry>
+	    <entry>Crop rectangle boundaries, in pixels.</entry>
+	  </row>
+	  <row>
+	    <entry>__u32</entry>
+	    <entry><structfield>reserved</structfield>[8]</entry>
+	    <entry>Reserved for future extensions. Applications and drivers must
+	    set the array to zero.</entry>
+	  </row>
+	</tbody>
+      </tgroup>
+    </table>
+
+  </refsect1>
+
+  <refsect1>
+    &return-value;
+
+    <variablelist>
+      <varlistentry>
+	<term><errorcode>EBUSY</errorcode></term>
+	<listitem>
+	  <para>The selection rectangle can't be changed because the
+	  pad is currently busy. This can be caused, for instance, by
+	  an active video stream on the pad. The ioctl must not be
+	  retried without performing another action to fix the problem
+	  first. Only returned by
+	  <constant>VIDIOC_SUBDEV_S_SELECTION</constant></para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><errorcode>EINVAL</errorcode></term>
+	<listitem>
+	  <para>The &v4l2-subdev-selection;
+	  <structfield>pad</structfield> references a non-existing
+	  pad, the <structfield>which</structfield> field references a
+	  non-existing format, or the selection target is not
+	  supported on the given subdev pad.</para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+</refentry>
Signature · 2 lines
Sakari Ailus
[email protected]
#26 lore raw

Re: [RFC 06/17] v4l: Add selections documentation.

Hi Sakari,

Quoted 14 lines

Hi Laurent,

Thanks for the comments!

Quoted 9 lines · Laurent Pinchart

On Tuesday 20 December 2011 21:27:58 Sakari Ailus wrote:

[snip]

Quoted 5 lines
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/dev-subdev.xml index 0916a73..722db60 100644

Documentation/DocBook/media/v4l/dev-subdev.xml +0 -0

[snip]

Quoted 32 lines
Quoted 5 lines

This sounds a bit confusing to me. One issue is that composing is not formally defined. I think it would help if you could draw a diagram that shows how the operations are applied, and modify the text to describe the diagram, using the natural order of the compose and crop operations on sink and source pads.

I drew a diagram based on your suggestion, but I'd prefer the formal definition would come from someone who needs composition and better understands the use cases.

Also cc Tomasz.

Quoted 13 lines

Documentation/DocBook/media/v4l/dev-subdev.xml line 336

Quoted 12 lines

+<section>
+<title>Order of configuration and format propagation</title>

Documentation/DocBook/media/v4l/dev-subdev.xml +10 -0
+
+<para>The order of image processing steps will always be from
+      the sink pad towards the source pad. This is also reflected in
+      the order in which the configuration must be performed by the
+      user. The format is propagated within the subdev along the later
+      processing steps. For example, setting the sink pad format
+      causes all the selection rectangles and the source pad format to
+      be set to sink pad format --- if allowed by the hardware, and if
+      not, then closest possible. The coordinates to a step always
+      refer to the active size of the previous step.</para>
Quoted 4 lines

This also sounds a bit ambiguous if I try to ignore the fact that I know how it works :-) You should at least make it explicit that propagation inside subdevs is performed by the driver(s), and that propagation outside subdevs is to be handled by userspace.

Agreed. I'll reword it.

[snip]

Quoted 7 lines
Quoted 7 lines

Documentation/DocBook/media/v4l/dev-subdev.xml

Quoted 5 lines

+<para>The are four types of selection targets: active, default,

Documentation/DocBook/media/v4l/dev-subdev.xml +4 -0
+      bounds and padding. The ACTIVE targets are the targets which
+      configure the hardware. The DEFAULT target provides the default
+      for the ACTIVE selection. The BOUNDS target will return the
+      maximum width and height of the target.

What about the minimum ?

There are multiple problems with idea of the maximal rectangle because one has to provide definition how to compare size of two rectangles. If you had to compare rectangles 10x1, 1x10, 5x5 which would you choose as the largest? Such problems may appear if HW has width, height and size constraints. One encounters similar problem with definition of the smallest rectangle. I prefer to define "is larger" as "contains". Rectangle 10x10 contains all three overmentioned rectangles therefore it is the maximal rectangle. The problem with such a definition is that such a rectangle may not be accepted by HW.

Quoted 4 lines

Good question. We could also specify that the minimum is obtained by using the V4L2_SUBDEV_SEL_FLAG_LE flag with the BOUNDS target.

As I remember bounds rectangle is fixed and there is no such a thing as minimal/maximal bounds. For V4L2 video node API, the bounds rectangle is read-only value describing rectangle that contains all pixels. Could you describe the use case that utilities minimal bounds rectangle?

Quoted 5 lines
Quoted 4 lines
Quoted 2 lines

The PADDED target
+ provides the width and height for the padded image,

Is it valid for both crop and compose rectangles ?

Quoted 7 lines

I think all targets are valid for all rectangles. Should I mention that?

The practical use cases may be more limited, though. I wonder if I should remove the padded targets until we get use cases for them. I included them for the reason that they also exist in the V4L2.

Tomasz, Sylwester: do you have use for the PADDED targets?

S5P-TV and S5P-JPEG (by Andrzej Pietrasiewicz) makes use of PADDED target. The padded target is very hardware/application dependent parameter. It is defined only for composing targets. Basically it refers to all pixels that are modified by the hardware. In S5P-TV the padded rectangle is equal to active rectangle. However, if having no good idea about padded area, then it is always safe/consistent to make padded rectangle equal to bounds one.

Quoted 7 lines

I think we also must define what will be done in cases where crop (on either sink or source) / scaling / composition is not supported by the subdev. That's currently undefined. I think it'd be most clear to return an error code but I'm not sure which one --- EINVAL is an obvious candidate but that is also returned when the pad is wrong. It looks still like the best choice to me.

Maybe one should return EPERM or EACCES if S_SELECTION is called on read-only target. Other idea is to introduce V4L2_SEL_FLAG_RDONLY flag which is set by VIDIOC_G_SELECTION for a given target. The driver may return EINVAL if target is not supported. It would imply that support for the target is not implemented in the driver.

Regards,
Tomasz Stanislawski

Quoted 11 lines
Quoted 6 lines

Documentation/DocBook/media/v4l/dev-subdev.xml

Quoted 4 lines

and is

Documentation/DocBook/media/v4l/dev-subdev.xml +2 -0
+      directly affected by the ACTIVE target. The PADDED targets may
+      be configurable depending on the hardware.</para>

If that's configurable drivers will need a way to store it in the file handle.

Good point. I'll add it if we end up defining the padded targets now.

Quoted 2 lines
Quoted 2 lines

+</section>
+

#27 lore raw

Re: [RFC 06/17] v4l: Add selections documentation.

Hi Tomasz,

Thanks for your reply.

Quoted 74 lines · Tomasz Stanislawski
Quoted 10 lines
Quoted 9 lines · Laurent Pinchart

On Tuesday 20 December 2011 21:27:58 Sakari Ailus wrote:

[snip]

Quoted 5 lines
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/dev-subdev.xml index 0916a73..722db60 100644

Documentation/DocBook/media/v4l/dev-subdev.xml +0 -0

[snip]

Quoted 39 lines
Quoted 9 lines

This sounds a bit confusing to me. One issue is that composing is not formally
defined. I think it would help if you could draw a diagram that shows how the
operations are applied, and modify the text to describe the diagram, using the
natural order of the compose and crop operations on sink and source pads.

I drew a diagram based on your suggestion, but I'd prefer the formal definition would come from someone who needs composition and better understands the use cases.

Also cc Tomasz.

Quoted 13 lines

Documentation/DocBook/media/v4l/dev-subdev.xml line 336

Quoted 12 lines

+<section>
+<title>Order of configuration and format propagation</title>

Documentation/DocBook/media/v4l/dev-subdev.xml +10 -0
+
+<para>The order of image processing steps will always be from
+      the sink pad towards the source pad. This is also reflected in
+      the order in which the configuration must be performed by the
+      user. The format is propagated within the subdev along the later
+      processing steps. For example, setting the sink pad format
+      causes all the selection rectangles and the source pad format to
+      be set to sink pad format --- if allowed by the hardware, and if
+      not, then closest possible. The coordinates to a step always
+      refer to the active size of the previous step.</para>
Quoted 7 lines

This also sounds a bit ambiguous if I try to ignore the fact that I know how
it works :-) You should at least make it explicit that propagation inside
subdevs is performed by the driver(s), and that propagation outside subdevs is
to be handled by userspace.

Agreed. I'll reword it.

[snip]

Quoted 7 lines
Quoted 7 lines

Documentation/DocBook/media/v4l/dev-subdev.xml

Quoted 5 lines

+<para>The are four types of selection targets: active, default,

Documentation/DocBook/media/v4l/dev-subdev.xml +4 -0
+      bounds and padding. The ACTIVE targets are the targets which
+      configure the hardware. The DEFAULT target provides the default
+      for the ACTIVE selection. The BOUNDS target will return the
+      maximum width and height of the target.

What about the minimum ?

There are multiple problems with idea of the maximal rectangle because one has to provide definition how to compare size of two rectangles. If you had to compare rectangles 10x1, 1x10, 5x5 which would you choose as the largest? Such problems may appear if HW has width, height and size constraints. One encounters similar problem with definition of the smallest rectangle. I prefer to define "is larger" as "contains". Rectangle 10x10 contains all three overmentioned rectangles therefore it is the maximal rectangle. The problem with such a definition is that such a rectangle may not be accepted by HW.

Quoted 1 line
Quoted 8 lines
Quoted 3 lines

Good question. We could also specify that the minimum is obtained by using the V4L2_SUBDEV_SEL_FLAG_LE flag with the BOUNDS target.

As I remember bounds rectangle is fixed and there is no such a thing as minimal/maximal bounds. For V4L2 video node API, the bounds rectangle is read-only value describing rectangle that contains all pixels. Could you describe the use case that utilities minimal bounds rectangle?

Most devices do have a minimum width and height for the image they can process. This is typically relatively large: from 32 pixels to around 200 pixels. Not that these limits typically would be hit in practice, but it might still be good to be able to tell they exist.

The user will notice that from the rectangle returned from s_selection, too.

But from your explanation I understand that the bounds rectangle is something different. In which situations the bounds rectangle would be different from the active one?

Quoted 13 lines
Quoted 5 lines
Quoted 4 lines
Quoted 2 lines

The PADDED target
+ provides the width and height for the padded image,

Is it valid for both crop and compose rectangles ?

Quoted 7 lines

I think all targets are valid for all rectangles. Should I mention that?

The practical use cases may be more limited, though. I wonder if I should remove the padded targets until we get use cases for them. I included them for the reason that they also exist in the V4L2.

Tomasz, Sylwester: do you have use for the PADDED targets?

Quoted 7 lines

S5P-TV and S5P-JPEG (by Andrzej Pietrasiewicz) makes use of PADDED target. The padded target is very hardware/application dependent parameter. It is defined only for composing targets. Basically it refers to all pixels that are modified by the hardware. In S5P-TV the padded rectangle is equal to active rectangle. However, if having no good idea about padded area, then it is always safe/consistent to make padded rectangle equal to bounds one.

Why not the active target?

If the hardware modifies more pixels in composition than really wanted, isn't that an issue? Or do you think it'd be the responsibility of the subdev at the other end of the link to discard it?

I'm beginning to wonder if padded or bounds target makes sense for subdevs. Don't get me wrong --- I would just like to understad the use case for them.

Quoted 7 lines
Quoted 6 lines

I think we also must define what will be done in cases where crop (on either sink or source) / scaling / composition is not supported by the subdev. That's currently undefined. I think it'd be most clear to return an error code but I'm not sure which one --- EINVAL is an obvious candidate but that is also returned when the pad is wrong. It looks still like the best choice to me.

Quoted 5 lines

Maybe one should return EPERM or EACCES if S_SELECTION is called on read-only target. Other idea is to introduce V4L2_SEL_FLAG_RDONLY flag which is set by VIDIOC_G_SELECTION for a given target. The driver may return EINVAL if target is not supported. It would imply that support for the target is not implemented in the driver.

That brings us to another question: if a subdev does not support something, for example scaling, should it provide a way to get, or even set the related rectangle? Providing a way to get it might well make sense, but to set it should likely, as you propose, return EACCES (EPERM suggests it's a permission issue which it isn't).

Opinions?

Regards,

Signature · 2 lines
Sakari Ailus
[email protected]
#28 lore raw

Re: [RFC 06/17] v4l: Add selections documentation.

In reply to Sakari Ailus

Hi Sakari,

Quoted 2 lines · On Monday 09 January 2012 19:16:16 Sakari Ailus wrote:
Quoted 1 line · Laurent Pinchart

On Tuesday 20 December 2011 21:27:58 Sakari Ailus wrote:

[snip]

Quoted 11 lines
Quoted 4 lines
Quoted 2 lines

The PADDED target
+ provides the width and height for the padded image,

Is it valid for both crop and compose rectangles ?

I think all targets are valid for all rectangles. Should I mention that?

The practical use cases may be more limited, though. I wonder if I should remove the padded targets until we get use cases for them. I included them for the reason that they also exist in the V4L2.

Quoted 8 lines

Tomasz, Sylwester: do you have use for the PADDED targets?

I think we also must define what will be done in cases where crop (on either sink or source) / scaling / composition is not supported by the subdev. That's currently undefined. I think it'd be most clear to return an error code but I'm not sure which one --- EINVAL is an obvious candidate but that is also returned when the pad is wrong. It looks still like the best choice to me.

If the rectangle isn't supported, EINVAL is appropriate. Do we need a way to discover what rectangles are supported ?

If the rectangle is supported by the size is out of range, the driver should adjust it instead of returning an error.

Signature · 3 lines
Regards,

Laurent Pinchart
#29 lore raw

RFC 7/17 v4l: Add pixelrate to struct v4l2_mbus_framefmt

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

Pixelrate is an essential part of the image data parameters. Add this. Together, the current parameters also define the frame rate.

Sensors do not have a concept of frame rate; pixelrate is much more meaningful in this context. Also, it is best to combine the pixelrate with the other format parameters since there are dependencies between them.

---
 Documentation/DocBook/media/v4l/subdev-formats.xml |   10 +++++++++-
 include/linux/v4l2-mediabus.h                      |    4 +++-
 2 files changed, 12 insertions(+), 2 deletions(-)
Documentation/DocBook/media/v4l/subdev-formats.xml +9 -1
index 49c532e..a6a6630 100644
@@ -35,7 +35,15 @@
 	</row>
 	<row>
 	  <entry>__u32</entry>
-	  <entry><structfield>reserved</structfield>[7]</entry>
+	  <entry><structfield>pixelrate</structfield></entry>
+	  <entry>Pixel rate in kp/s. This clock is the maximum rate at
+	  which pixels are transferred on the bus. The
+	  <structfield>pixelrate</structfield> field is
+	  read-only.</entry>
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>reserved</structfield>[6]</entry>
 	  <entry>Reserved for future extensions. Applications and drivers must
 	  set the array to zero.</entry>
 	</row>
include/linux/v4l2-mediabus.h +3 -1
index 5ea7f75..35c6b96 100644
@@ -101,6 +101,7 @@ enum v4l2_mbus_pixelcode {
  * @code:	data format code (from enum v4l2_mbus_pixelcode)
  * @field:	used interlacing type (from enum v4l2_field)
  * @colorspace:	colorspace of the data (from enum v4l2_colorspace)
+ * @pixel_clock: pixel clock, in kHz
  */
 struct v4l2_mbus_framefmt {
 	__u32			width;
@@ -108,7 +109,8 @@ struct v4l2_mbus_framefmt {
 	__u32			code;
 	__u32			field;
 	__u32			colorspace;
-	__u32			reserved[7];
+	__u32			pixelrate;
+	__u32			reserved[6];
 };
 
 #endif
Signature · 1 line
1.7.2.5
#30 lore raw

Re: [RFC 07/17] v4l: Add pixelrate to struct v4l2_mbus_framefmt

Hi Sakari,

Thanks for the patch.

Quoted 21 lines · On Tuesday 20 December 2011 21:27:59 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Pixelrate is an essential part of the image data parameters. Add this. Together, the current parameters also define the frame rate.

Sensors do not have a concept of frame rate; pixelrate is much more meaningful in this context. Also, it is best to combine the pixelrate with the other format parameters since there are dependencies between them.

---
 Documentation/DocBook/media/v4l/subdev-formats.xml |   10 +++++++++-
 include/linux/v4l2-mediabus.h                      |    4 +++-
 2 files changed, 12 insertions(+), 2 deletions(-)
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/subdev-formats.xml index 49c532e..a6a6630 100644

Documentation/DocBook/media/v4l/subdev-formats.xml line 39

Quoted 6 lines
Documentation/DocBook/media/v4l/subdev-formats.xml +2 -1
@@ -35,7 +35,15 @@
 	</row>
 	<row>
 	  <entry>__u32</entry>
-	  <entry><structfield>reserved</structfield>[7]</entry>
+	  <entry><structfield>pixelrate</structfield></entry>
+	  <entry>Pixel rate in kp/s.

kPix/s or kPixel/s ?

Quoted 1 line

This clock is the maximum rate at

Is it really a clock ?

Documentation/DocBook/media/v4l/subdev-formats.xml line 42

Quoted 3 lines
Documentation/DocBook/media/v4l/subdev-formats.xml +3 -0
+	  which pixels are transferred on the bus. The
+	  <structfield>pixelrate</structfield> field is
+	  read-only.</entry>

Does that mean that userspace isn't required to propagate the value down the pipeline when configuring it ? I'm fine with that, but it should probably be documented explictly somewhere to make sure that drivers don't rely on it.

Quoted 12 lines
Documentation/DocBook/media/v4l/subdev-formats.xml +4 -0
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>reserved</structfield>[6]</entry>
 	  <entry>Reserved for future extensions. Applications and drivers must
 	  set the array to zero.</entry>
 	</row>
include/linux/v4l2-mediabus.h +0 -0
index 5ea7f75..35c6b96 100644

include/linux/v4l2-mediabus.h enum v4l2_mbus_pixelcode { · line 104

Quoted 4 lines
include/linux/v4l2-mediabus.h +1 -0
@@ -101,6 +101,7 @@ enum v4l2_mbus_pixelcode {
  * @code:	data format code (from enum v4l2_mbus_pixelcode)
  * @field:	used interlacing type (from enum v4l2_field)
  * @colorspace:	colorspace of the data (from enum v4l2_colorspace)
+ * @pixel_clock: pixel clock, in kHz

I think you forgot to update the comment.

Quoted 13 lines
include/linux/v4l2-mediabus.h +2 -1
  */
 struct v4l2_mbus_framefmt {
 	__u32			width;
@@ -108,7 +109,8 @@ struct v4l2_mbus_framefmt {
 	__u32			code;
 	__u32			field;
 	__u32			colorspace;
-	__u32			reserved[7];
+	__u32			pixelrate;
+	__u32			reserved[6];
 };
 
 #endif
Signature · 3 lines
Regards,

Laurent Pinchart
#31 lore raw

Re: [RFC 07/17] v4l: Add pixelrate to struct v4l2_mbus_framefmt

Hi Laurent,

Quoted 16 lines · Laurent Pinchart
Quoted 15 lines · On Tuesday 20 December 2011 21:27:59 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Pixelrate is an essential part of the image data parameters. Add this. Together, the current parameters also define the frame rate.

Sensors do not have a concept of frame rate; pixelrate is much more meaningful in this context. Also, it is best to combine the pixelrate with the other format parameters since there are dependencies between them.

---
 Documentation/DocBook/media/v4l/subdev-formats.xml |   10 +++++++++-
 include/linux/v4l2-mediabus.h                      |    4 +++-
 2 files changed, 12 insertions(+), 2 deletions(-)
Quoted 14 lines

Documentation/DocBook/media/v4l/subdev-formats.xml line 39

Quoted 12 lines
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/subdev-formats.xml index 49c532e..a6a6630 100644

Documentation/DocBook/media/v4l/subdev-formats.xml +2 -1
@@ -35,7 +35,15 @@
 	</row>
 	<row>
 	  <entry>__u32</entry>
-	  <entry><structfield>reserved</structfield>[7]</entry>
+	  <entry><structfield>pixelrate</structfield></entry>
+	  <entry>Pixel rate in kp/s.

kPix/s or kPixel/s ?

Hmm. kilo-pixels / second?

Albeit I have to say I'm increasingly inclined to think this field doesn't really belong to this struct --- we should discuss that tomorrow.

There are two things this is needed in the user space:

1) To calculate detailed hardware timing information.

2) To figure out whether streaming is possible, or to figure out why it failed in case it did.

And in kernel space:

1) To configure devices. The OMAP 3 ISP CSI-2 receiver and CCDC blocks must be configured based on the pixel rate.

2) Validate pipeline pixel rate for each subdev. Some subdevs require it to be withint limits. A good example is the OMAP 3 ISP where most blocks have 100 Mp/s maximum whereas the CSI-2 receiver has 200 Mp/s maximum.

This could be implemented using pad-specific controls. In drivers the subdev in sink end of the link would get the controls from the source.

Quoted 45 lines
Quoted 1 line

This clock is the maximum rate at

Is it really a clock ?

Documentation/DocBook/media/v4l/subdev-formats.xml line 42

Quoted 3 lines
Documentation/DocBook/media/v4l/subdev-formats.xml +3 -0
+	  which pixels are transferred on the bus. The
+	  <structfield>pixelrate</structfield> field is
+	  read-only.</entry>

Does that mean that userspace isn't required to propagate the value down the pipeline when configuring it ? I'm fine with that, but it should probably be documented explictly somewhere to make sure that drivers don't rely on it.

Quoted 12 lines
Documentation/DocBook/media/v4l/subdev-formats.xml +4 -0
+	</row>
+	<row>
+	  <entry>__u32</entry>
+	  <entry><structfield>reserved</structfield>[6]</entry>
 	  <entry>Reserved for future extensions. Applications and drivers must
 	  set the array to zero.</entry>
 	</row>
include/linux/v4l2-mediabus.h +0 -0
index 5ea7f75..35c6b96 100644

include/linux/v4l2-mediabus.h enum v4l2_mbus_pixelcode { · line 104

Quoted 4 lines
include/linux/v4l2-mediabus.h +1 -0
@@ -101,6 +101,7 @@ enum v4l2_mbus_pixelcode {
  * @code:	data format code (from enum v4l2_mbus_pixelcode)
  * @field:	used interlacing type (from enum v4l2_field)
  * @colorspace:	colorspace of the data (from enum v4l2_colorspace)
+ * @pixel_clock: pixel clock, in kHz

I think you forgot to update the comment.

Quoted 13 lines
include/linux/v4l2-mediabus.h +2 -1
  */
 struct v4l2_mbus_framefmt {
 	__u32			width;
@@ -108,7 +109,8 @@ struct v4l2_mbus_framefmt {
 	__u32			code;
 	__u32			field;
 	__u32			colorspace;
-	__u32			reserved[7];
+	__u32			pixelrate;
+	__u32			reserved[6];
 };
 
 #endif
Signature · 2 lines
Sakari Ailus
[email protected]
#32 lore raw

RFC 8/17 v4l: Image source control class

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

Add image source control class. This control class is intended to contain low level controls which deal with control of the image capture process --- the A/D converter in image sensors, for example.

---
 Documentation/DocBook/media/v4l/controls.xml       |  101 ++++++++++++++++++++
 .../DocBook/media/v4l/vidioc-g-ext-ctrls.xml       |    6 +
 drivers/media/video/v4l2-ctrls.c                   |   10 ++
 include/linux/videodev2.h                          |   10 ++
 4 files changed, 127 insertions(+), 0 deletions(-)
Documentation/DocBook/media/v4l/controls.xml +101 -0
index 3bc5ee8..69ede83 100644
@@ -3356,6 +3356,107 @@ interface and may change in the future.</para>
       </table>
 
     </section>
+
+    <section id="image-source-controls">
+      <title>Image Source Control Reference</title>
+
+      <note>
+	<title>Experimental</title>
+
+	<para>This is an <link
+	linkend="experimental">experimental</link> interface and may
+	change in the future.</para>
+      </note>
+
+      <para>
+	The Image Source control class is intended for low-level
+	control of image source devices such as image sensors. The
+	devices feature an analogue to digital converter and a bus
+	transmitter to transmit the image data out of the device.
+      </para>
+
+      <table pgwide="1" frame="none" id="image-source-control-id">
+      <title>Image Source Control IDs</title>
+
+      <tgroup cols="4">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="6*" />
+	<colspec colname="c3" colwidth="2*" />
+	<colspec colname="c4" colwidth="6*" />
+	<spanspec namest="c1" nameend="c2" spanname="id" />
+	<spanspec namest="c2" nameend="c4" spanname="descr" />
+	<thead>
+	  <row>
+	    <entry spanname="id" align="left">ID</entry>
+	    <entry align="left">Type</entry>
+	  </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
+	  </row>
+	</thead>
+	<tbody valign="top">
+	  <row><entry></entry></row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant></entry>
+	    <entry>class</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">The IMAGE_SOURCE class descriptor.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_VBLANK</constant></entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Vertical blanking. The idle
+	    preriod after every frame during which no image data is
+	    produced. The unit of vertical blanking is a line. Every
+	    line has length of the image width plus horizontal
+	    blanking at the pixel clock specified by struct
+	    v4l2_mbus_framefmt <xref linkend="v4l2-mbus-framefmt"
+	    />.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_HBLANK</constant></entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Horizontal blanking. The idle
+	    preriod after every line of image data during which no
+	    image data is produced. The unit of horizontal blanking is
+	    pixels.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_LINK_FREQ</constant></entry>
+	    <entry>integer menu</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Image source's data bus frequency.
+	    Together with the media bus pixel code, bus type (clock
+	    cycles per sample), the data bus frequency defines the
+	    pixel clock. <xref linkend="v4l2-mbus-framefmt" /> The
+	    frame rate can be calculated from the pixel clock, image
+	    width and height and horizontal and vertical blanking. The
+	    frame rate control is performed by selecting the desired
+	    horizontal and vertical blanking.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN</constant></entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Analogue gain is gain affecting
+	    all colour components in the pixel matrix. The gain
+	    operation is performed in the analogue domain before A/D
+	    conversion.
+	    </entry>
+	  </row>
+	  <row><entry></entry></row>
+	</tbody>
+      </tgroup>
+      </table>
+
+    </section>
+
 </section>
 
   <!--
Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +6 -0
index 5122ce8..250c1cf 100644
@@ -257,6 +257,12 @@ These controls are described in <xref
 These controls are described in <xref
 		linkend="flash-controls" />.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_CLASS_IMAGE_SOURCE</constant></entry>
+	    <entry>0x9d0000</entry> <entry>The class containing image
+	    source controls. These controls are described in <xref
+	    linkend="image-source-controls" />.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
drivers/media/video/v4l2-ctrls.c +10 -0
index 083bb79..da1ec52 100644
@@ -606,6 +606,12 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_FLASH_CHARGE:		return "Charge";
 	case V4L2_CID_FLASH_READY:		return "Ready to strobe";
 
+	case V4L2_CID_IMAGE_SOURCE_CLASS:	return "Image source controls";
+	case V4L2_CID_IMAGE_SOURCE_VBLANK:	return "Vertical blanking";
+	case V4L2_CID_IMAGE_SOURCE_HBLANK:	return "Horizontal blanking";
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:	return "Link frequency";
+	case V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN: return "Analogue gain";
+
 	default:
 		return NULL;
 	}
@@ -694,6 +700,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
 		*type = V4L2_CTRL_TYPE_MENU;
 		break;
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:
+		*type = V4L2_CTRL_TYPE_INTEGER_MENU;
+		break;
 	case V4L2_CID_RDS_TX_PS_NAME:
 	case V4L2_CID_RDS_TX_RADIO_TEXT:
 		*type = V4L2_CTRL_TYPE_STRING;
@@ -703,6 +712,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_MPEG_CLASS:
 	case V4L2_CID_FM_TX_CLASS:
 	case V4L2_CID_FLASH_CLASS:
+	case V4L2_CID_IMAGE_SOURCE_CLASS:
 		*type = V4L2_CTRL_TYPE_CTRL_CLASS;
 		/* You can neither read not write these */
 		*flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
include/linux/videodev2.h +10 -0
index 9633c69..0f8f904 100644
@@ -1080,6 +1080,7 @@ struct v4l2_ext_controls {
 #define V4L2_CTRL_CLASS_CAMERA 0x009a0000	/* Camera class controls */
 #define V4L2_CTRL_CLASS_FM_TX 0x009b0000	/* FM Modulator control class */
 #define V4L2_CTRL_CLASS_FLASH 0x009c0000	/* Camera flash controls */
+#define V4L2_CTRL_CLASS_IMAGE_SOURCE 0x009d0000	/* Image source flash controls */
 
 #define V4L2_CTRL_ID_MASK      	  (0x0fffffff)
 #define V4L2_CTRL_ID2CLASS(id)    ((id) & 0x0fff0000UL)
@@ -1690,6 +1691,15 @@ enum v4l2_flash_strobe_source {
 #define V4L2_CID_FLASH_CHARGE			(V4L2_CID_FLASH_CLASS_BASE + 11)
 #define V4L2_CID_FLASH_READY			(V4L2_CID_FLASH_CLASS_BASE + 12)
 
+/* Image source controls */
+#define V4L2_CID_IMAGE_SOURCE_CLASS_BASE	(V4L2_CTRL_CLASS_IMAGE_SOURCE | 0x900)
+#define V4L2_CID_IMAGE_SOURCE_CLASS		(V4L2_CTRL_CLASS_IMAGE_SOURCE | 1)
+
+#define V4L2_CID_IMAGE_SOURCE_VBLANK		(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 1)
+#define V4L2_CID_IMAGE_SOURCE_HBLANK		(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2)
+#define V4L2_CID_IMAGE_SOURCE_LINK_FREQ		(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3)
+#define V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN	(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 4)
+
 /*
  *	T U N I N G
  */
Signature · 1 line
1.7.2.5
#33 lore raw

Re: [RFC 08/17] v4l: Image source control class

Hi Sakari,

Thanks for the patch.

Quoted 29 lines · On Tuesday 20 December 2011 21:28:00 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add image source control class. This control class is intended to contain low level controls which deal with control of the image capture process --- the A/D converter in image sensors, for example.

---
 Documentation/DocBook/media/v4l/controls.xml       |  101 +++++++++++++++++
 .../DocBook/media/v4l/vidioc-g-ext-ctrls.xml       |    6 +
 drivers/media/video/v4l2-ctrls.c                   |   10 ++
 include/linux/videodev2.h                          |   10 ++
 4 files changed, 127 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/controls.xml index 3bc5ee8..69ede83 100644

Documentation/DocBook/media/v4l/controls.xml +6 -0
@@ -3356,6 +3356,107 @@ interface and may change in the future.</para>
       </table>
 
     </section>
+
+    <section id="image-source-controls">
+      <title>Image Source Control Reference</title>
+
+      <note>
+	<title>Experimental</title>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3374

Quoted 10 lines
Documentation/DocBook/media/v4l/controls.xml +10 -0
+
+	<para>This is an <link
+	linkend="experimental">experimental</link> interface and may
+	change in the future.</para>
+      </note>
+
+      <para>
+	The Image Source control class is intended for low-level
+	control of image source devices such as image sensors. The
+	devices feature an analogue to digital converter and a bus

Is the V4L2 documentation written in US or UK English ? US uses analog, UK uses analogue. Analog would be shorter in control names.

Quoted 34 lines
Documentation/DocBook/media/v4l/controls.xml +18 -0
+	transmitter to transmit the image data out of the device.
+      </para>
+
+      <table pgwide="1" frame="none" id="image-source-control-id">
+      <title>Image Source Control IDs</title>
+
+      <tgroup cols="4">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="6*" />
+	<colspec colname="c3" colwidth="2*" />
+	<colspec colname="c4" colwidth="6*" />
+	<spanspec namest="c1" nameend="c2" spanname="id" />
+	<spanspec namest="c2" nameend="c4" spanname="descr" />
+	<thead>
+	  <row>
+	    <entry spanname="id" align="left">ID</entry>
+	    <entry align="left">Type</entry>
+	  </row><row rowsep="1"><entry spanname="descr"

align="left">Description</entry> + </row>

Documentation/DocBook/media/v4l/controls.xml +5 -0
+	</thead>
+	<tbody valign="top">
+	  <row><entry></entry></row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant></entry> +
<entry>class</entry>

Documentation/DocBook/media/v4l/controls.xml +6 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">The IMAGE_SOURCE class descriptor.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_VBLANK</constant></entry> +
<entry>integer</entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3410

Quoted 4 lines
Documentation/DocBook/media/v4l/controls.xml +4 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Vertical blanking. The idle
+	    preriod after every frame during which no image data is

s/preriod/period/

Quoted 10 lines
Documentation/DocBook/media/v4l/controls.xml +8 -0
+	    produced. The unit of vertical blanking is a line. Every
+	    line has length of the image width plus horizontal
+	    blanking at the pixel clock specified by struct
+	    v4l2_mbus_framefmt <xref linkend="v4l2-mbus-framefmt"
+	    />.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_HBLANK</constant></entry> +
<entry>integer</entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3423

Quoted 4 lines
Documentation/DocBook/media/v4l/controls.xml +4 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Horizontal blanking. The idle
+	    preriod after every line of image data during which no

s/preriod/period/

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3432

Quoted 10 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+	    image data is produced. The unit of horizontal blanking is
+	    pixels.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_LINK_FREQ</constant></entry>

Documentation/DocBook/media/v4l/controls.xml +4 -0
+	    <entry>integer menu</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Image source's data bus frequency.

What's the frequency unit ? Sample/second ?

Quoted 13 lines
Documentation/DocBook/media/v4l/controls.xml +11 -0
+	    Together with the media bus pixel code, bus type (clock
+	    cycles per sample), the data bus frequency defines the
+	    pixel clock. <xref linkend="v4l2-mbus-framefmt" /> The
+	    frame rate can be calculated from the pixel clock, image
+	    width and height and horizontal and vertical blanking. The
+	    frame rate control is performed by selecting the desired
+	    horizontal and vertical blanking.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN</constant></en
try> + <entry>integer</entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3450

Quoted 6 lines
Documentation/DocBook/media/v4l/controls.xml +6 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Analogue gain is gain affecting
+	    all colour components in the pixel matrix. The gain
+	    operation is performed in the analogue domain before A/D
+	    conversion.

Should we define one gain per color component ?

Quoted 35 lines
Documentation/DocBook/media/v4l/controls.xml +9 -0
+	    </entry>
+	  </row>
+	  <row><entry></entry></row>
+	</tbody>
+      </tgroup>
+      </table>
+
+    </section>
+
 </section>
 
   <!--
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml index 5122ce8..250c1cf 100644

Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +6 -0
@@ -257,6 +257,12 @@ These controls are described in <xref
 These controls are described in <xref
 		linkend="flash-controls" />.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_CLASS_IMAGE_SOURCE</constant></entry>
+	    <entry>0x9d0000</entry> <entry>The class containing image
+	    source controls. These controls are described in <xref
+	    linkend="image-source-controls" />.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
(quoted diff) +0 -0

b/drivers/media/video/v4l2-ctrls.c index 083bb79..da1ec52 100644

drivers/media/video/v4l2-ctrls.c const char *v4l2_ctrl_get_name(u32 id) · line 613

Quoted 8 lines
drivers/media/video/v4l2-ctrls.c +5 -0
@@ -606,6 +606,12 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_FLASH_CHARGE:		return "Charge";
 	case V4L2_CID_FLASH_READY:		return "Ready to strobe";
 
+	case V4L2_CID_IMAGE_SOURCE_CLASS:	return "Image source controls";
+	case V4L2_CID_IMAGE_SOURCE_VBLANK:	return "Vertical blanking";
+	case V4L2_CID_IMAGE_SOURCE_HBLANK:	return "Horizontal blanking";
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:	return "Link frequency";
+	case V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN: return "Analogue gain";

Please capitalize each word, as done for the other controls.

drivers/media/video/v4l2-ctrls.c void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, · line 705

Quoted 10 lines
drivers/media/video/v4l2-ctrls.c +0 -0
 	default:
 		return NULL;
 	}
@@ -694,6 +700,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum

v4l2_ctrl_type *type, case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:

drivers/media/video/v4l2-ctrls.c +3 -0
 		*type = V4L2_CTRL_TYPE_MENU;
 		break;
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:
+		*type = V4L2_CTRL_TYPE_INTEGER_MENU;
+		break;

Will this always be an integer menu control, or can you foresee cases where the range would be continuous ?

We already have drivers for Aptina parallel sensors that include a configurable PLL. The pixel clock can be configured more or less freely in that case, although I'm not sure if that's useful in practice.

Quoted 30 lines
drivers/media/video/v4l2-ctrls.c +0 -0
 	case V4L2_CID_RDS_TX_PS_NAME:
 	case V4L2_CID_RDS_TX_RADIO_TEXT:
 		*type = V4L2_CTRL_TYPE_STRING;
@@ -703,6 +712,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum

v4l2_ctrl_type *type, case V4L2_CID_MPEG_CLASS:

drivers/media/video/v4l2-ctrls.c +1 -0
 	case V4L2_CID_FM_TX_CLASS:
 	case V4L2_CID_FLASH_CLASS:
+	case V4L2_CID_IMAGE_SOURCE_CLASS:
 		*type = V4L2_CTRL_TYPE_CTRL_CLASS;
 		/* You can neither read not write these */
 		*flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
include/linux/videodev2.h +1 -0
index 9633c69..0f8f904 100644
@@ -1080,6 +1080,7 @@ struct v4l2_ext_controls {
 #define V4L2_CTRL_CLASS_CAMERA 0x009a0000	/* Camera class controls */
 #define V4L2_CTRL_CLASS_FM_TX 0x009b0000	/* FM Modulator control class */
 #define V4L2_CTRL_CLASS_FLASH 0x009c0000	/* Camera flash controls */
+#define V4L2_CTRL_CLASS_IMAGE_SOURCE 0x009d0000	/* Image source flash

controls */

#define V4L2_CTRL_ID_MASK (0x0fffffff)
#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)

include/linux/videodev2.h +2 -0
@@ -1690,6 +1691,15 @@ enum v4l2_flash_strobe_source {
 #define V4L2_CID_FLASH_CHARGE			(V4L2_CID_FLASH_CLASS_BASE + 11)
 #define V4L2_CID_FLASH_READY			(V4L2_CID_FLASH_CLASS_BASE + 12)
 
+/* Image source controls */
+#define V4L2_CID_IMAGE_SOURCE_CLASS_BASE	(V4L2_CTRL_CLASS_IMAGE_SOURCE |
Quoted 1 line

0x900) +#define V4L2_CID_IMAGE_SOURCE_CLASS

(V4L2_CTRL_CLASS_IMAGE_SOURCE

Quoted 2 lines

| 1) +
+#define V4L2_CID_IMAGE_SOURCE_VBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE

+

Quoted 10 lines

1) +#define
V4L2_CID_IMAGE_SOURCE_HBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2)
+#define
V4L2_CID_IMAGE_SOURCE_LINK_FREQ (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3)
+#define
V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 4)
+
/*
* T U N I N G
*/

Signature · 3 lines
Regards,

Laurent Pinchart
#34 lore raw

Re: [RFC 08/17] v4l: Image source control class

Hi Laurent,

Thanks for the review!

Quoted 35 lines · Laurent Pinchart
Quoted 34 lines · On Tuesday 20 December 2011 21:28:00 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add image source control class. This control class is intended to contain low level controls which deal with control of the image capture process --- the A/D converter in image sensors, for example.

---
 Documentation/DocBook/media/v4l/controls.xml       |  101 +++++++++++++++++
 .../DocBook/media/v4l/vidioc-g-ext-ctrls.xml       |    6 +
 drivers/media/video/v4l2-ctrls.c                   |   10 ++
 include/linux/videodev2.h                          |   10 ++
 4 files changed, 127 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/controls.xml index 3bc5ee8..69ede83 100644

Documentation/DocBook/media/v4l/controls.xml +11 -0
@@ -3356,6 +3356,107 @@ interface and may change in the future.</para>
       </table>
 
     </section>
+
+    <section id="image-source-controls">
+      <title>Image Source Control Reference</title>
+
+      <note>
+	<title>Experimental</title>
+
+	<para>This is an <link
+	linkend="experimental">experimental</link> interface and may
+	change in the future.</para>
+      </note>
Quoted 8 lines

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3374

Quoted 5 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+
+      <para>
+	The Image Source control class is intended for low-level
+	control of image source devices such as image sensors. The
+	devices feature an analogue to digital converter and a bus

Is the V4L2 documentation written in US or UK English ? US uses analog, UK uses analogue. Analog would be shorter in control names.

Both appear to be used, but the US English appears to be more commonly used. I guess it's mostly chosen by whatever happened to be used by the author of the patch. I prefer UK spelling which you might have noticed already. :-)

I remember there was a discussion on this topic years ago within the kernel community but I don't remember how it ended up with... LWN.net appears to remember better than I do, but by a quick check I can't find any definitive conclusion.

<URL:http://lwn.net/Articles/44262/>
<URL:http://lkml.org/lkml/2003/8/7/245>

Quoted 58 lines
Quoted 34 lines
Documentation/DocBook/media/v4l/controls.xml +18 -0
+	transmitter to transmit the image data out of the device.
+      </para>
+
+      <table pgwide="1" frame="none" id="image-source-control-id">
+      <title>Image Source Control IDs</title>
+
+      <tgroup cols="4">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="6*" />
+	<colspec colname="c3" colwidth="2*" />
+	<colspec colname="c4" colwidth="6*" />
+	<spanspec namest="c1" nameend="c2" spanname="id" />
+	<spanspec namest="c2" nameend="c4" spanname="descr" />
+	<thead>
+	  <row>
+	    <entry spanname="id" align="left">ID</entry>
+	    <entry align="left">Type</entry>
+	  </row><row rowsep="1"><entry spanname="descr"

align="left">Description</entry> + </row>

Documentation/DocBook/media/v4l/controls.xml +5 -0
+	</thead>
+	<tbody valign="top">
+	  <row><entry></entry></row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant></entry> +
<entry>class</entry>

Documentation/DocBook/media/v4l/controls.xml +6 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">The IMAGE_SOURCE class descriptor.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_VBLANK</constant></entry> +
<entry>integer</entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3410

Quoted 4 lines
Documentation/DocBook/media/v4l/controls.xml +4 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Vertical blanking. The idle
+	    preriod after every frame during which no image data is

s/preriod/period/

Quoted 10 lines
Documentation/DocBook/media/v4l/controls.xml +8 -0
+	    produced. The unit of vertical blanking is a line. Every
+	    line has length of the image width plus horizontal
+	    blanking at the pixel clock specified by struct
+	    v4l2_mbus_framefmt <xref linkend="v4l2-mbus-framefmt"
+	    />.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_HBLANK</constant></entry> +
<entry>integer</entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3423

Quoted 4 lines
Documentation/DocBook/media/v4l/controls.xml +4 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Horizontal blanking. The idle
+	    preriod after every line of image data during which no

s/preriod/period/

Quoted 12 lines

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3432

Quoted 10 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+	    image data is produced. The unit of horizontal blanking is
+	    pixels.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_LINK_FREQ</constant></entry>

Documentation/DocBook/media/v4l/controls.xml +4 -0
+	    <entry>integer menu</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Image source's data bus frequency.

What's the frequency unit ? Sample/second ?

Hz --- that's the unit of frequency. I fixed that in the new version.

Quoted 13 lines
Quoted 13 lines
Documentation/DocBook/media/v4l/controls.xml +11 -0
+	    Together with the media bus pixel code, bus type (clock
+	    cycles per sample), the data bus frequency defines the
+	    pixel clock. <xref linkend="v4l2-mbus-framefmt" /> The
+	    frame rate can be calculated from the pixel clock, image
+	    width and height and horizontal and vertical blanking. The
+	    frame rate control is performed by selecting the desired
+	    horizontal and vertical blanking.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN</constant></en
try> + <entry>integer</entry>

Quoted 8 lines

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3450

Quoted 6 lines
Documentation/DocBook/media/v4l/controls.xml +6 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Analogue gain is gain affecting
+	    all colour components in the pixel matrix. The gain
+	    operation is performed in the analogue domain before A/D
+	    conversion.

Should we define one gain per color component ?

I think that in the end we may need up to six analogue gains:

- Gain for all components
- Blue gain
- Red gain
- Green gain (for both greens)
- Gr gain
- Gb gain

It may be debatable whether Gr / Gb gain will always be the same or not. I'm not fully certain about that. As Hans G. suggested, it might be possible to go with just one for green.

Quoted 38 lines
Quoted 38 lines
Documentation/DocBook/media/v4l/controls.xml +9 -0
+	    </entry>
+	  </row>
+	  <row><entry></entry></row>
+	</tbody>
+      </tgroup>
+      </table>
+
+    </section>
+
 </section>
 
   <!--
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml index 5122ce8..250c1cf 100644

Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +6 -0
@@ -257,6 +257,12 @@ These controls are described in <xref
 These controls are described in <xref
 		linkend="flash-controls" />.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_CLASS_IMAGE_SOURCE</constant></entry>
+	    <entry>0x9d0000</entry> <entry>The class containing image
+	    source controls. These controls are described in <xref
+	    linkend="image-source-controls" />.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
(quoted diff) +0 -0

b/drivers/media/video/v4l2-ctrls.c index 083bb79..da1ec52 100644

drivers/media/video/v4l2-ctrls.c +0 -0
@@ -606,6 +606,12 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_FLASH_CHARGE:		return "Charge";
 	case V4L2_CID_FLASH_READY:		return "Ready to strobe";
 
Quoted 7 lines

drivers/media/video/v4l2-ctrls.c const char *v4l2_ctrl_get_name(u32 id) · line 613

Quoted 5 lines
drivers/media/video/v4l2-ctrls.c +5 -0
+	case V4L2_CID_IMAGE_SOURCE_CLASS:	return "Image source controls";
+	case V4L2_CID_IMAGE_SOURCE_VBLANK:	return "Vertical blanking";
+	case V4L2_CID_IMAGE_SOURCE_HBLANK:	return "Horizontal blanking";
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:	return "Link frequency";
+	case V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN: return "Analogue gain";

Please capitalize each word, as done for the other controls.

This isn't done for the flash controls either, have you noticed that?

Well, I guess I have to admit that they were added by myself. ;-)

I can fix this for the next patchset.

Quoted 5 lines
Quoted 5 lines
drivers/media/video/v4l2-ctrls.c +0 -0
 	default:
 		return NULL;
 	}
@@ -694,6 +700,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum

v4l2_ctrl_type *type, case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:

Quoted 8 lines

drivers/media/video/v4l2-ctrls.c void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, · line 705

Quoted 5 lines
drivers/media/video/v4l2-ctrls.c +3 -0
 		*type = V4L2_CTRL_TYPE_MENU;
 		break;
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:
+		*type = V4L2_CTRL_TYPE_INTEGER_MENU;
+		break;

Will this always be an integer menu control, or can you foresee cases where the range would be continuous ?

Good question. On some hardware this definitely is an integer menu, but hardware may exist where more selections would be available.

However, on e.g. the SMIA++ sensor the calculation of the clock tree values depends heavily on the selected link rate. Choosing a wrong link rate may yield to the clock tree calculation to fail. So the driver likely would need to enforce some rules which values are allowed. That might prove unfeasible --- already the PLL code in the SMIA++ driver is relatively complex.

I don't see much benefit in being able to specify this freely.

AFAIR the conclusion was that controls may only have one type when the control framework was written.

Quoted 50 lines

We already have drivers for Aptina parallel sensors that include a configurable PLL. The pixel clock can be configured more or less freely in that case, although I'm not sure if that's useful in practice.

Quoted 30 lines
drivers/media/video/v4l2-ctrls.c +0 -0
 	case V4L2_CID_RDS_TX_PS_NAME:
 	case V4L2_CID_RDS_TX_RADIO_TEXT:
 		*type = V4L2_CTRL_TYPE_STRING;
@@ -703,6 +712,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum

v4l2_ctrl_type *type, case V4L2_CID_MPEG_CLASS:

drivers/media/video/v4l2-ctrls.c +1 -0
 	case V4L2_CID_FM_TX_CLASS:
 	case V4L2_CID_FLASH_CLASS:
+	case V4L2_CID_IMAGE_SOURCE_CLASS:
 		*type = V4L2_CTRL_TYPE_CTRL_CLASS;
 		/* You can neither read not write these */
 		*flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
include/linux/videodev2.h +1 -0
index 9633c69..0f8f904 100644
@@ -1080,6 +1080,7 @@ struct v4l2_ext_controls {
 #define V4L2_CTRL_CLASS_CAMERA 0x009a0000	/* Camera class controls */
 #define V4L2_CTRL_CLASS_FM_TX 0x009b0000	/* FM Modulator control class */
 #define V4L2_CTRL_CLASS_FLASH 0x009c0000	/* Camera flash controls */
+#define V4L2_CTRL_CLASS_IMAGE_SOURCE 0x009d0000	/* Image source flash

controls */

#define V4L2_CTRL_ID_MASK (0x0fffffff)
#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)

include/linux/videodev2.h +2 -0
@@ -1690,6 +1691,15 @@ enum v4l2_flash_strobe_source {
 #define V4L2_CID_FLASH_CHARGE			(V4L2_CID_FLASH_CLASS_BASE + 11)
 #define V4L2_CID_FLASH_READY			(V4L2_CID_FLASH_CLASS_BASE + 12)
 
+/* Image source controls */
+#define V4L2_CID_IMAGE_SOURCE_CLASS_BASE	(V4L2_CTRL_CLASS_IMAGE_SOURCE |
Quoted 1 line

0x900) +#define V4L2_CID_IMAGE_SOURCE_CLASS

(V4L2_CTRL_CLASS_IMAGE_SOURCE

Quoted 2 lines

| 1) +
+#define V4L2_CID_IMAGE_SOURCE_VBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE

+

Quoted 10 lines

1) +#define
V4L2_CID_IMAGE_SOURCE_HBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2)
+#define
V4L2_CID_IMAGE_SOURCE_LINK_FREQ (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3)
+#define
V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 4)
+
/*
* T U N I N G
*/

Signature · 2 lines
Sakari Ailus
[email protected]
#35 lore raw

Re: [RFC 08/17] v4l: Image source control class

Hi Sakari,

Quoted 49 lines · On Saturday 14 January 2012 21:51:31 Sakari Ailus wrote:
Quoted 39 lines · Laurent Pinchart
Quoted 38 lines · On Tuesday 20 December 2011 21:28:00 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add image source control class. This control class is intended to contain low level controls which deal with control of the image capture process --- the A/D converter in image sensors, for example.

---

 Documentation/DocBook/media/v4l/controls.xml       |  101
 +++++++++++++++++ .../DocBook/media/v4l/vidioc-g-ext-ctrls.xml       |
    6 +
 drivers/media/video/v4l2-ctrls.c                   |   10 ++
 include/linux/videodev2.h                          |   10 ++
 4 files changed, 127 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/controls.xml index 3bc5ee8..69ede83 100644

Documentation/DocBook/media/v4l/controls.xml +11 -0
@@ -3356,6 +3356,107 @@ interface and may change in the future.</para>
 
       </table>
 
     </section>
 
+
+    <section id="image-source-controls">
+      <title>Image Source Control Reference</title>
+
+      <note>
+	<title>Experimental</title>
+
+	<para>This is an <link
+	linkend="experimental">experimental</link> interface and may
+	change in the future.</para>
+      </note>
Quoted 8 lines

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3374

Quoted 5 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+
+      <para>
+	The Image Source control class is intended for low-level
+	control of image source devices such as image sensors. The
+	devices feature an analogue to digital converter and a bus

Is the V4L2 documentation written in US or UK English ? US uses analog, UK uses analogue. Analog would be shorter in control names.

Quoted 4 lines

Both appear to be used, but the US English appears to be more commonly used. I guess it's mostly chosen by whatever happened to be used by the author of the patch. I prefer UK spelling which you might have noticed already. :-)

Yes I have. I haven't checked whether V4L2 prefers the UK or US spelling. I'll trust you on that.

Quoted 87 lines

I remember there was a discussion on this topic years ago within the kernel community but I don't remember how it ended up with... LWN.net appears to remember better than I do, but by a quick check I can't find any definitive conclusion.

<URL:http://lwn.net/Articles/44262/>
<URL:http://lkml.org/lkml/2003/8/7/245>

Quoted 66 lines
Quoted 35 lines
Documentation/DocBook/media/v4l/controls.xml +18 -0
+	transmitter to transmit the image data out of the device.
+      </para>
+
+      <table pgwide="1" frame="none" id="image-source-control-id">
+      <title>Image Source Control IDs</title>
+
+      <tgroup cols="4">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="6*" />
+	<colspec colname="c3" colwidth="2*" />
+	<colspec colname="c4" colwidth="6*" />
+	<spanspec namest="c1" nameend="c2" spanname="id" />
+	<spanspec namest="c2" nameend="c4" spanname="descr" />
+	<thead>
+	  <row>
+	    <entry spanname="id" align="left">ID</entry>
+	    <entry align="left">Type</entry>
+	  </row><row rowsep="1"><entry spanname="descr"

align="left">Description</entry> + </row>

Documentation/DocBook/media/v4l/controls.xml +5 -0
+	</thead>
+	<tbody valign="top">
+	  <row><entry></entry></row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant></entry> +

<entry>class</entry>

Documentation/DocBook/media/v4l/controls.xml +6 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">The IMAGE_SOURCE class descriptor.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_VBLANK</constant></entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3410

Quoted 8 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+
 
   <entry>integer</entry>
 
+	  </row>
+	  <row>
+	    <entry spanname="descr">Vertical blanking. The idle
+	    preriod after every frame during which no image data is

s/preriod/period/

Quoted 9 lines
Documentation/DocBook/media/v4l/controls.xml +8 -0
+	    produced. The unit of vertical blanking is a line. Every
+	    line has length of the image width plus horizontal
+	    blanking at the pixel clock specified by struct
+	    v4l2_mbus_framefmt <xref linkend="v4l2-mbus-framefmt"
+	    />.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_HBLANK</constant></entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3423

Quoted 8 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+
 
   <entry>integer</entry>
 
+	  </row>
+	  <row>
+	    <entry spanname="descr">Horizontal blanking. The idle
+	    preriod after every line of image data during which no

s/preriod/period/

Quoted 12 lines

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3432

Quoted 10 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+	    image data is produced. The unit of horizontal blanking is
+	    pixels.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_LINK_FREQ</constant></entr
y> + <entry>integer menu</entry>

Documentation/DocBook/media/v4l/controls.xml +3 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Image source's data bus frequency.

What's the frequency unit ? Sample/second ?

Quoted 1 line

Hz --- that's the unit of frequency. I fixed that in the new version.

Is the user supposed to compute the pixel clock from this information ? That's what the text below seems to imply.

Quoted 22 lines
Quoted 13 lines
Quoted 13 lines
Documentation/DocBook/media/v4l/controls.xml +11 -0
+	    Together with the media bus pixel code, bus type (clock
+	    cycles per sample), the data bus frequency defines the
+	    pixel clock. <xref linkend="v4l2-mbus-framefmt" /> The
+	    frame rate can be calculated from the pixel clock, image
+	    width and height and horizontal and vertical blanking. The
+	    frame rate control is performed by selecting the desired
+	    horizontal and vertical blanking.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN</constant></
en try> + <entry>integer</entry>

Quoted 8 lines

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3450

Quoted 6 lines
Documentation/DocBook/media/v4l/controls.xml +6 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Analogue gain is gain affecting
+	    all colour components in the pixel matrix. The gain
+	    operation is performed in the analogue domain before A/D
+	    conversion.

Should we define one gain per color component ?

Quoted 3 lines

I think that in the end we may need up to six analogue gains:

- Gain for all components

Many sensors that provide per-component gains also provide a global gain control that sets the four component gains. I'm not sure how (and if) we should handle that.

Quoted 9 lines

- Blue gain
- Red gain
- Green gain (for both greens)
- Gr gain
- Gb gain

It may be debatable whether Gr / Gb gain will always be the same or not. I'm not fully certain about that. As Hans G. suggested, it might be possible to go with just one for green.

I'm also unsure about that. Having different gains for the two green components doesn't seem very useful. On the other hand, if we find a use case later, we'll have to break driver ABIs.

Quoted 84 lines
Quoted 49 lines
Quoted 49 lines
Documentation/DocBook/media/v4l/controls.xml +9 -0
+	    </entry>
+	  </row>
+	  <row><entry></entry></row>
+	</tbody>
+      </tgroup>
+      </table>
+
+    </section>
+
 
 </section>
 
   <!--
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml index 5122ce8..250c1cf 100644

Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +6 -0
@@ -257,6 +257,12 @@ These controls are described in <xref
 
 These controls are described in <xref
 
 		linkend="flash-controls" />.</entry>
 
 	  </row>
 
+	  <row>
+	    <entry><constant>V4L2_CTRL_CLASS_IMAGE_SOURCE</constant></entry>
+	    <entry>0x9d0000</entry> <entry>The class containing image
+	    source controls. These controls are described in <xref
+	    linkend="image-source-controls" />.</entry>
+	  </row>
 
 	</tbody>
 
       </tgroup>
 
     </table>
(quoted diff) +0 -0

b/drivers/media/video/v4l2-ctrls.c index 083bb79..da1ec52 100644

drivers/media/video/v4l2-ctrls.c +0 -0
@@ -606,6 +606,12 @@ const char *v4l2_ctrl_get_name(u32 id)
 
 	case V4L2_CID_FLASH_CHARGE:		return "Charge";
 	case V4L2_CID_FLASH_READY:		return "Ready to strobe";
 
Quoted 7 lines

drivers/media/video/v4l2-ctrls.c const char *v4l2_ctrl_get_name(u32 id) · line 613

Quoted 5 lines
drivers/media/video/v4l2-ctrls.c +5 -0
+	case V4L2_CID_IMAGE_SOURCE_CLASS:	return "Image source controls";
+	case V4L2_CID_IMAGE_SOURCE_VBLANK:	return "Vertical blanking";
+	case V4L2_CID_IMAGE_SOURCE_HBLANK:	return "Horizontal blanking";
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:	return "Link frequency";
+	case V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN: return "Analogue gain";

Please capitalize each word, as done for the other controls.

This isn't done for the flash controls either, have you noticed that?

Well, I guess I have to admit that they were added by myself. ;-)

I can fix this for the next patchset.

Quoted 11 lines
Quoted 11 lines
drivers/media/video/v4l2-ctrls.c +0 -0
 	default:
 		return NULL;
 
 	}
@@ -694,6 +700,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum
 

v4l2_ctrl_type *type, case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:

drivers/media/video/v4l2-ctrls.c +0 -0
 		*type = V4L2_CTRL_TYPE_MENU;
 		break;
Quoted 6 lines

drivers/media/video/v4l2-ctrls.c void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, · line 705

Quoted 3 lines
drivers/media/video/v4l2-ctrls.c +3 -0
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:
+		*type = V4L2_CTRL_TYPE_INTEGER_MENU;
+		break;

Will this always be an integer menu control, or can you foresee cases where the range would be continuous ?

Good question. On some hardware this definitely is an integer menu, but hardware may exist where more selections would be available.

Quoted 8 lines

However, on e.g. the SMIA++ sensor the calculation of the clock tree values depends heavily on the selected link rate. Choosing a wrong link rate may yield to the clock tree calculation to fail. So the driver likely would need to enforce some rules which values are allowed. That might prove unfeasible --- already the PLL code in the SMIA++ driver is relatively complex.

I don't see much benefit in being able to specify this freely.

For SMIA++, definitely not. For other sensors, I don't know.

Quoted 2 lines

AFAIR the conclusion was that controls may only have one type when the control framework was written.

Yes, but I'm not sure whether that's a good conclusion :-)

Quoted 48 lines
Quoted 48 lines

We already have drivers for Aptina parallel sensors that include a configurable PLL. The pixel clock can be configured more or less freely in that case, although I'm not sure if that's useful in practice.

Quoted 40 lines
drivers/media/video/v4l2-ctrls.c +0 -0
 	case V4L2_CID_RDS_TX_PS_NAME:
 
 	case V4L2_CID_RDS_TX_RADIO_TEXT:
 		*type = V4L2_CTRL_TYPE_STRING;
@@ -703,6 +712,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum
 

v4l2_ctrl_type *type, case V4L2_CID_MPEG_CLASS:

drivers/media/video/v4l2-ctrls.c +1 -0
 	case V4L2_CID_FM_TX_CLASS:
 
 	case V4L2_CID_FLASH_CLASS:
+	case V4L2_CID_IMAGE_SOURCE_CLASS:
 		*type = V4L2_CTRL_TYPE_CTRL_CLASS;
 		/* You can neither read not write these */
 		*flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_WRITE_ONLY;
include/linux/videodev2.h +1 -0
index 9633c69..0f8f904 100644
@@ -1080,6 +1080,7 @@ struct v4l2_ext_controls {
 
 #define V4L2_CTRL_CLASS_CAMERA 0x009a0000	/* Camera class controls */
 #define V4L2_CTRL_CLASS_FM_TX 0x009b0000	/* FM Modulator control class
 */ #define V4L2_CTRL_CLASS_FLASH 0x009c0000	/* Camera flash controls
 */
 
+#define V4L2_CTRL_CLASS_IMAGE_SOURCE 0x009d0000	/* Image source flash

controls */

#define V4L2_CTRL_ID_MASK (0x0fffffff)
#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)

include/linux/videodev2.h +2 -0
@@ -1690,6 +1691,15 @@ enum v4l2_flash_strobe_source {
 
 #define V4L2_CID_FLASH_CHARGE			(V4L2_CID_FLASH_CLASS_BASE + 11)
 #define V4L2_CID_FLASH_READY			(V4L2_CID_FLASH_CLASS_BASE + 12)
 
+/* Image source controls */
+#define V4L2_CID_IMAGE_SOURCE_CLASS_BASE	(V4L2_CTRL_CLASS_IMAGE_SOURCE
Quoted 1 line

| 0x900) +#define V4L2_CID_IMAGE_SOURCE_CLASS

(V4L2_CTRL_CLASS_IMAGE_SOURCE

Quoted 3 lines
Quoted 3 lines
Quoted 3 lines

| 1) +

+#define V4L2_CID_IMAGE_SOURCE_VBLANK

(V4L2_CID_IMAGE_SOURCE_CLASS_BASE

Quoted 7 lines
Quoted 7 lines

+

Quoted 4 lines

1) +#define
V4L2_CID_IMAGE_SOURCE_HBLANK (V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2)
+#define
V4L2_CID_IMAGE_SOURCE_LINK_FREQ (V4L2_CID_IMAGE_SOURCE_CLASS_BASE

+ 3)

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

+#define
V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN (V4L2_CID_IMAGE_SOURCE_CLASS_BASE

+

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

4) +

/*

* T U N I N G
*/

Signature · 3 lines
Regards,

Laurent Pinchart
#36 lore raw

Re: [RFC 08/17] v4l: Image source control class

Hi Laurent,

Quoted 50 lines · Laurent Pinchart
Quoted 49 lines · On Saturday 14 January 2012 21:51:31 Sakari Ailus wrote:
Quoted 47 lines · Laurent Pinchart
Quoted 33 lines · On Tuesday 20 December 2011 21:28:00 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add image source control class. This control class is intended to contain low level controls which deal with control of the image capture process --- the A/D converter in image sensors, for example.

---

 Documentation/DocBook/media/v4l/controls.xml       |  101
 +++++++++++++++++ .../DocBook/media/v4l/vidioc-g-ext-ctrls.xml       |
    6 +
 drivers/media/video/v4l2-ctrls.c                   |   10 ++
 include/linux/videodev2.h                          |   10 ++
 4 files changed, 127 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/controls.xml index 3bc5ee8..69ede83 100644

Documentation/DocBook/media/v4l/controls.xml +6 -0
@@ -3356,6 +3356,107 @@ interface and may change in the future.</para>
 
       </table>
 
     </section>
 
+
+    <section id="image-source-controls">
+      <title>Image Source Control Reference</title>
+
+      <note>
+	<title>Experimental</title>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3376

Quoted 10 lines
Documentation/DocBook/media/v4l/controls.xml +10 -0
+
+	<para>This is an <link
+	linkend="experimental">experimental</link> interface and may
+	change in the future.</para>
+      </note>
+
+      <para>
+	The Image Source control class is intended for low-level
+	control of image source devices such as image sensors. The
+	devices feature an analogue to digital converter and a bus

Is the V4L2 documentation written in US or UK English ? US uses analog, UK uses analogue. Analog would be shorter in control names.

Quoted 7 lines
Quoted 4 lines

Both appear to be used, but the US English appears to be more commonly used. I guess it's mostly chosen by whatever happened to be used by the author of the patch. I prefer UK spelling which you might have noticed already. :-)

Yes I have. I haven't checked whether V4L2 prefers the UK or US spelling. I'll trust you on that.

I have checked and most seem to have used US spelling. If you wish me to change it, I can do that.

Quoted 87 lines
Quoted 87 lines

I remember there was a discussion on this topic years ago within the kernel community but I don't remember how it ended up with... LWN.net appears to remember better than I do, but by a quick check I can't find any definitive conclusion.

<URL:http://lwn.net/Articles/44262/>
<URL:http://lkml.org/lkml/2003/8/7/245>

Quoted 78 lines
Quoted 35 lines
Documentation/DocBook/media/v4l/controls.xml +18 -0
+	transmitter to transmit the image data out of the device.
+      </para>
+
+      <table pgwide="1" frame="none" id="image-source-control-id">
+      <title>Image Source Control IDs</title>
+
+      <tgroup cols="4">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="6*" />
+	<colspec colname="c3" colwidth="2*" />
+	<colspec colname="c4" colwidth="6*" />
+	<spanspec namest="c1" nameend="c2" spanname="id" />
+	<spanspec namest="c2" nameend="c4" spanname="descr" />
+	<thead>
+	  <row>
+	    <entry spanname="id" align="left">ID</entry>
+	    <entry align="left">Type</entry>
+	  </row><row rowsep="1"><entry spanname="descr"

align="left">Description</entry> + </row>

Documentation/DocBook/media/v4l/controls.xml +5 -0
+	</thead>
+	<tbody valign="top">
+	  <row><entry></entry></row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant></entry> +

<entry>class</entry>

Documentation/DocBook/media/v4l/controls.xml +6 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">The IMAGE_SOURCE class descriptor.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_VBLANK</constant></entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3410

Quoted 8 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+
 
   <entry>integer</entry>
 
+	  </row>
+	  <row>
+	    <entry spanname="descr">Vertical blanking. The idle
+	    preriod after every frame during which no image data is

s/preriod/period/

Quoted 9 lines
Documentation/DocBook/media/v4l/controls.xml +8 -0
+	    produced. The unit of vertical blanking is a line. Every
+	    line has length of the image width plus horizontal
+	    blanking at the pixel clock specified by struct
+	    v4l2_mbus_framefmt <xref linkend="v4l2-mbus-framefmt"
+	    />.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_HBLANK</constant></entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3423

Quoted 8 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+
 
   <entry>integer</entry>
 
+	  </row>
+	  <row>
+	    <entry spanname="descr">Horizontal blanking. The idle
+	    preriod after every line of image data during which no

s/preriod/period/

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3432

Quoted 10 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+	    image data is produced. The unit of horizontal blanking is
+	    pixels.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_LINK_FREQ</constant></entr
y> + <entry>integer menu</entry>

Documentation/DocBook/media/v4l/controls.xml +3 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Image source's data bus frequency.

What's the frequency unit ? Sample/second ?

Quoted 4 lines
Quoted 1 line

Hz --- that's the unit of frequency. I fixed that in the new version.

Is the user supposed to compute the pixel clock from this information ? That's what the text below seems to imply.

Apparently I have forgotten to update this in the new patchset. But yes, these factors do define it. The sensors' internal clock tree will be involved and calculation is non-trivial. This is why we also have the PIXEL_RATE control --- where I will refer to in the next patchset.

Quoted 22 lines
Quoted 22 lines
Quoted 21 lines
Quoted 13 lines
Documentation/DocBook/media/v4l/controls.xml +11 -0
+	    Together with the media bus pixel code, bus type (clock
+	    cycles per sample), the data bus frequency defines the
+	    pixel clock. <xref linkend="v4l2-mbus-framefmt" /> The
+	    frame rate can be calculated from the pixel clock, image
+	    width and height and horizontal and vertical blanking. The
+	    frame rate control is performed by selecting the desired
+	    horizontal and vertical blanking.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN</constant></
en try> + <entry>integer</entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3450

Quoted 6 lines
Documentation/DocBook/media/v4l/controls.xml +6 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Analogue gain is gain affecting
+	    all colour components in the pixel matrix. The gain
+	    operation is performed in the analogue domain before A/D
+	    conversion.

Should we define one gain per color component ?

Quoted 7 lines
Quoted 3 lines

I think that in the end we may need up to six analogue gains:

- Gain for all components

Many sensors that provide per-component gains also provide a global gain control that sets the four component gains. I'm not sure how (and if) we should handle that.

If it directly affects all of them, I don't think we should support it. But if it's independent of the colour-specific ones, then, sure, it should be supported.

Quoted 6 lines
Quoted 6 lines

- Blue gain
- Red gain
- Green gain (for both greens)
- Gr gain
- Gb gain

Quoted 7 lines
Quoted 3 lines

It may be debatable whether Gr / Gb gain will always be the same or not. I'm not fully certain about that. As Hans G. suggested, it might be possible to go with just one for green.

I'm also unsure about that. Having different gains for the two green components doesn't seem very useful. On the other hand, if we find a use case later, we'll have to break driver ABIs.

Let's add the gains later on. Now we'll need a single analogue gain for all components and that's good for the time being.

Quoted 91 lines
Quoted 91 lines
Quoted 49 lines
Quoted 49 lines
Documentation/DocBook/media/v4l/controls.xml +9 -0
+	    </entry>
+	  </row>
+	  <row><entry></entry></row>
+	</tbody>
+      </tgroup>
+      </table>
+
+    </section>
+
 
 </section>
 
   <!--
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml index 5122ce8..250c1cf 100644

Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +6 -0
@@ -257,6 +257,12 @@ These controls are described in <xref
 
 These controls are described in <xref
 
 		linkend="flash-controls" />.</entry>
 
 	  </row>
 
+	  <row>
+	    <entry><constant>V4L2_CTRL_CLASS_IMAGE_SOURCE</constant></entry>
+	    <entry>0x9d0000</entry> <entry>The class containing image
+	    source controls. These controls are described in <xref
+	    linkend="image-source-controls" />.</entry>
+	  </row>
 
 	</tbody>
 
       </tgroup>
 
     </table>
(quoted diff) +0 -0

b/drivers/media/video/v4l2-ctrls.c index 083bb79..da1ec52 100644

drivers/media/video/v4l2-ctrls.c +0 -0
@@ -606,6 +606,12 @@ const char *v4l2_ctrl_get_name(u32 id)
 
 	case V4L2_CID_FLASH_CHARGE:		return "Charge";
 	case V4L2_CID_FLASH_READY:		return "Ready to strobe";
 
Quoted 7 lines

drivers/media/video/v4l2-ctrls.c const char *v4l2_ctrl_get_name(u32 id) · line 613

Quoted 5 lines
drivers/media/video/v4l2-ctrls.c +5 -0
+	case V4L2_CID_IMAGE_SOURCE_CLASS:	return "Image source controls";
+	case V4L2_CID_IMAGE_SOURCE_VBLANK:	return "Vertical blanking";
+	case V4L2_CID_IMAGE_SOURCE_HBLANK:	return "Horizontal blanking";
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:	return "Link frequency";
+	case V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN: return "Analogue gain";

Please capitalize each word, as done for the other controls.

This isn't done for the flash controls either, have you noticed that?

Well, I guess I have to admit that they were added by myself. ;-)

I can fix this for the next patchset.

Quoted 11 lines
Quoted 11 lines
drivers/media/video/v4l2-ctrls.c +0 -0
 	default:
 		return NULL;
 
 	}
@@ -694,6 +700,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum
 

v4l2_ctrl_type *type, case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:

drivers/media/video/v4l2-ctrls.c +0 -0
 		*type = V4L2_CTRL_TYPE_MENU;
 		break;
Quoted 6 lines

drivers/media/video/v4l2-ctrls.c void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, · line 705

Quoted 3 lines
drivers/media/video/v4l2-ctrls.c +3 -0
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:
+		*type = V4L2_CTRL_TYPE_INTEGER_MENU;
+		break;

Will this always be an integer menu control, or can you foresee cases where the range would be continuous ?

Good question. On some hardware this definitely is an integer menu, but hardware may exist where more selections would be available.

However, on e.g. the SMIA++ sensor the calculation of the clock tree values depends heavily on the selected link rate. Choosing a wrong link rate may yield to the clock tree calculation to fail. So the driver likely would need to enforce some rules which values are allowed. That might prove unfeasible --- already the PLL code in the SMIA++ driver is relatively complex.

Quoted 3 lines
Quoted 1 line

I don't see much benefit in being able to specify this freely.

For SMIA++, definitely not. For other sensors, I don't know.

At least one Aptina sensor had a clock tree which basically had a few dividers and a multiplier. The same restrictions apply.

Quoted 4 lines
Quoted 2 lines

AFAIR the conclusion was that controls may only have one type when the control framework was written.

Yes, but I'm not sure whether that's a good conclusion :-)

It allows you to assume a type for controls, whether that's good or not.

This could be one use case for that, but I don't really see much advantage in (attepmpting) to support fully free sensor link frequency configuration.

Regards,

Signature · 2 lines
Sakari Ailus
[email protected]
#37 lore raw

Re: [RFC 08/17] v4l: Image source control class

Hi Sakari,

Quoted 59 lines · On Sunday 15 January 2012 20:44:02 Sakari Ailus wrote:
Quoted 58 lines · Laurent Pinchart
Quoted 56 lines · On Saturday 14 January 2012 21:51:31 Sakari Ailus wrote:
Quoted 42 lines · Laurent Pinchart
Quoted 41 lines · On Tuesday 20 December 2011 21:28:00 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add image source control class. This control class is intended to contain low level controls which deal with control of the image capture process --- the A/D converter in image sensors, for example.

---

 Documentation/DocBook/media/v4l/controls.xml       |  101

+++++++++++++++++ .../DocBook/media/v4l/vidioc-g-ext-ctrls.xml |

    6 +
 drivers/media/video/v4l2-ctrls.c                   |   10 ++
 include/linux/videodev2.h                          |   10 ++
 4 files changed, 127 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/controls.xml index 3bc5ee8..69ede83 100644

Documentation/DocBook/media/v4l/controls.xml +11 -0
@@ -3356,6 +3356,107 @@ interface and may change in the future.</para>
 
       </table>
 
     </section>
 
+
+    <section id="image-source-controls">
+      <title>Image Source Control Reference</title>
+
+      <note>
+	<title>Experimental</title>
+
+	<para>This is an <link
+	linkend="experimental">experimental</link> interface and may
+	change in the future.</para>
+      </note>
Quoted 8 lines

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3374

Quoted 5 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+
+      <para>
+	The Image Source control class is intended for low-level
+	control of image source devices such as image sensors. The
+	devices feature an analogue to digital converter and a bus

Is the V4L2 documentation written in US or UK English ? US uses analog, UK uses analogue. Analog would be shorter in control names.

Both appear to be used, but the US English appears to be more commonly used. I guess it's mostly chosen by whatever happened to be used by the author of the patch. I prefer UK spelling which you might have noticed already. :-)

Quoted 5 lines
Quoted 2 lines

Yes I have. I haven't checked whether V4L2 prefers the UK or US spelling. I'll trust you on that.

I have checked and most seem to have used US spelling. If you wish me to change it, I can do that.

As you (and others) wish.

Quoted 90 lines
Quoted 90 lines
Quoted 89 lines

I remember there was a discussion on this topic years ago within the kernel community but I don't remember how it ended up with... LWN.net appears to remember better than I do, but by a quick check I can't find any definitive conclusion.

<URL:http://lwn.net/Articles/44262/>
<URL:http://lkml.org/lkml/2003/8/7/245>

Quoted 67 lines
Quoted 40 lines
Documentation/DocBook/media/v4l/controls.xml +18 -0
+	transmitter to transmit the image data out of the device.
+      </para>
+
+      <table pgwide="1" frame="none" id="image-source-control-id">
+      <title>Image Source Control IDs</title>
+
+      <tgroup cols="4">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="6*" />
+	<colspec colname="c3" colwidth="2*" />
+	<colspec colname="c4" colwidth="6*" />
+	<spanspec namest="c1" nameend="c2" spanname="id" />
+	<spanspec namest="c2" nameend="c4" spanname="descr" />
+	<thead>
+	  <row>
+	    <entry spanname="id" align="left">ID</entry>
+	    <entry align="left">Type</entry>
+	  </row><row rowsep="1"><entry spanname="descr"

align="left">Description</entry> + </row>

Documentation/DocBook/media/v4l/controls.xml +5 -0
+	</thead>
+	<tbody valign="top">
+	  <row><entry></entry></row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant></entry>

Documentation/DocBook/media/v4l/controls.xml +4 -0
+
 
  <entry>class</entry>
 
+	  </row>
+	  <row>
+	    <entry spanname="descr">The IMAGE_SOURCE class

descriptor.</entry> + </row>

Documentation/DocBook/media/v4l/controls.xml +2 -0
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_VBLANK</constant></entry

Quoted 1 line

+

<entry>integer</entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3410

Quoted 4 lines
Documentation/DocBook/media/v4l/controls.xml +4 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Vertical blanking. The idle
+	    preriod after every frame during which no image data is

s/preriod/period/

Quoted 13 lines
Documentation/DocBook/media/v4l/controls.xml +8 -0
+	    produced. The unit of vertical blanking is a line. Every
+	    line has length of the image width plus horizontal
+	    blanking at the pixel clock specified by struct
+	    v4l2_mbus_framefmt <xref linkend="v4l2-mbus-framefmt"
+	    />.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_HBLANK</constant></entry

Quoted 1 line

+

<entry>integer</entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3423

Quoted 4 lines
Documentation/DocBook/media/v4l/controls.xml +4 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Horizontal blanking. The idle
+	    preriod after every line of image data during which no

s/preriod/period/

Quoted 12 lines

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3432

Quoted 10 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+	    image data is produced. The unit of horizontal blanking is
+	    pixels.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_LINK_FREQ</constant></en
tr y> + <entry>integer menu</entry>

Documentation/DocBook/media/v4l/controls.xml +3 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Image source's data bus frequency.

What's the frequency unit ? Sample/second ?

Hz --- that's the unit of frequency. I fixed that in the new version.

Quoted 7 lines
Quoted 2 lines

Is the user supposed to compute the pixel clock from this information ? That's what the text below seems to imply.

Apparently I have forgotten to update this in the new patchset. But yes, these factors do define it. The sensors' internal clock tree will be involved and calculation is non-trivial. This is why we also have the PIXEL_RATE control --- where I will refer to in the next patchset.

How is the sensor clock tree involved ? My understanding is that it will define the data bus frequency based on the sensor input clock, but the bus data rate shouldn't be influenced by the clock tree for a given bus frequency.

Computing the pixel rate from the bus frequency isn't trivial and shouldn't be done by userspace if my understanding is correct. Documenting all this clearly would probably help :-)

Quoted 26 lines
Quoted 26 lines
Quoted 25 lines
Quoted 13 lines
Quoted 13 lines
Documentation/DocBook/media/v4l/controls.xml +11 -0
+	    Together with the media bus pixel code, bus type (clock
+	    cycles per sample), the data bus frequency defines the
+	    pixel clock. <xref linkend="v4l2-mbus-framefmt" /> The
+	    frame rate can be calculated from the pixel clock, image
+	    width and height and horizontal and vertical blanking. The
+	    frame rate control is performed by selecting the desired
+	    horizontal and vertical blanking.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN</constant>
</ en try> + <entry>integer</entry>

Quoted 8 lines

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3450

Quoted 6 lines
Documentation/DocBook/media/v4l/controls.xml +6 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Analogue gain is gain affecting
+	    all colour components in the pixel matrix. The gain
+	    operation is performed in the analogue domain before A/D
+	    conversion.

Should we define one gain per color component ?

I think that in the end we may need up to six analogue gains:

- Gain for all components

Quoted 7 lines
Quoted 3 lines

Many sensors that provide per-component gains also provide a global gain control that sets the four component gains. I'm not sure how (and if) we should handle that.

If it directly affects all of them, I don't think we should support it. But if it's independent of the colour-specific ones, then, sure, it should be supported.

It directly affects them. It's a shortcut. Maybe the R, G and B gain controls should then be put in a cluster, and if the user sets them to the same value the driver would optimize I2C communication by using the global gain control.

Quoted 38 lines
Quoted 6 lines
Quoted 6 lines

- Blue gain
- Red gain
- Green gain (for both greens)
- Gr gain
- Gb gain

Quoted 7 lines
Quoted 3 lines

It may be debatable whether Gr / Gb gain will always be the same or not. I'm not fully certain about that. As Hans G. suggested, it might be possible to go with just one for green.

I'm also unsure about that. Having different gains for the two green components doesn't seem very useful. On the other hand, if we find a use case later, we'll have to break driver ABIs.

Let's add the gains later on. Now we'll need a single analogue gain for all components and that's good for the time being.

Quoted 21 lines
Quoted 21 lines
Quoted 21 lines
Quoted 21 lines
Documentation/DocBook/media/v4l/controls.xml +9 -0
+	    </entry>
+	  </row>
+	  <row><entry></entry></row>
+	</tbody>
+      </tgroup>
+      </table>
+
+    </section>
+
 
 </section>
 
   <!--
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml index 5122ce8..250c1cf 100644

Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +0 -0
@@ -257,6 +257,12 @@ These controls are described in <xref
 
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines

Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml These controls are described in <xref

Quoted 8 lines
Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +2 -0
 These controls are described in <xref
 
 		linkend="flash-controls" />.</entry>
 
 	  </row>
 
+	  <row>
+	    

<entry><constant>V4L2_CTRL_CLASS_IMAGE_SOURCE</constant></entry>

Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Quoted 17 lines
Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +4 -0
+	    <entry>0x9d0000</entry> <entry>The class containing image
+	    source controls. These controls are described in <xref
+	    linkend="image-source-controls" />.</entry>
+	  </row>
 
 	</tbody>
 
       </tgroup>
 
     </table>
(quoted diff) +0 -0

b/drivers/media/video/v4l2-ctrls.c index 083bb79..da1ec52 100644

drivers/media/video/v4l2-ctrls.c +0 -0
@@ -606,6 +606,12 @@ const char *v4l2_ctrl_get_name(u32 id)
 
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines

drivers/media/video/v4l2-ctrls.c const char *v4l2_ctrl_get_name(u32 id)

Quoted 4 lines
drivers/media/video/v4l2-ctrls.c +1 -0
 	case V4L2_CID_FLASH_CHARGE:		return "Charge";
 	case V4L2_CID_FLASH_READY:		return "Ready to strobe";
 
+	case V4L2_CID_IMAGE_SOURCE_CLASS:	return "Image source 

controls";

Quoted 52 lines
Quoted 42 lines
Quoted 42 lines
Quoted 6 lines

drivers/media/video/v4l2-ctrls.c const char *v4l2_ctrl_get_name(u32 id) · line 613

Quoted 4 lines
drivers/media/video/v4l2-ctrls.c +4 -0
+	case V4L2_CID_IMAGE_SOURCE_VBLANK:	return "Vertical blanking";
+	case V4L2_CID_IMAGE_SOURCE_HBLANK:	return "Horizontal blanking";
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:	return "Link frequency";
+	case V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN: return "Analogue gain";

Please capitalize each word, as done for the other controls.

This isn't done for the flash controls either, have you noticed that?

Well, I guess I have to admit that they were added by myself. ;-)

I can fix this for the next patchset.

Quoted 12 lines
Quoted 12 lines
drivers/media/video/v4l2-ctrls.c +0 -0
 	default:
 		return NULL;
 
 	}
@@ -694,6 +700,9 @@ void v4l2_ctrl_fill(u32 id, const char **name,

enum

v4l2_ctrl_type *type, case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:

drivers/media/video/v4l2-ctrls.c +0 -0
 		*type = V4L2_CTRL_TYPE_MENU;
 		break;
Quoted 6 lines

drivers/media/video/v4l2-ctrls.c void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type, · line 705

Quoted 3 lines
drivers/media/video/v4l2-ctrls.c +3 -0
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:
+		*type = V4L2_CTRL_TYPE_INTEGER_MENU;
+		break;

Will this always be an integer menu control, or can you foresee cases where the range would be continuous ?

Good question. On some hardware this definitely is an integer menu, but hardware may exist where more selections would be available.

However, on e.g. the SMIA++ sensor the calculation of the clock tree values depends heavily on the selected link rate. Choosing a wrong link rate may yield to the clock tree calculation to fail. So the driver likely would need to enforce some rules which values are allowed. That might prove unfeasible --- already the PLL code in the SMIA++ driver is relatively complex.

Quoted 3 lines
Quoted 1 line

I don't see much benefit in being able to specify this freely.

For SMIA++, definitely not. For other sensors, I don't know.

At least one Aptina sensor had a clock tree which basically had a few dividers and a multiplier. The same restrictions apply.

Quoted 3 lines
Quoted 2 lines

AFAIR the conclusion was that controls may only have one type when the control framework was written.

Quoted 7 lines
Quoted 1 line

Yes, but I'm not sure whether that's a good conclusion :-)

It allows you to assume a type for controls, whether that's good or not.

This could be one use case for that, but I don't really see much advantage in (attepmpting) to support fully free sensor link frequency configuration.

Who will then be responsible for creating the list of available frequencies ?

Signature · 3 lines
Regards,

Laurent Pinchart
#38 lore raw

Re: [RFC 08/17] v4l: Image source control class

Hi Laurent,

Quoted 161 lines · Laurent Pinchart
Quoted 59 lines · On Sunday 15 January 2012 20:44:02 Sakari Ailus wrote:
Quoted 58 lines · Laurent Pinchart
Quoted 56 lines · On Saturday 14 January 2012 21:51:31 Sakari Ailus wrote:
Quoted 42 lines · Laurent Pinchart
Quoted 41 lines · On Tuesday 20 December 2011 21:28:00 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add image source control class. This control class is intended to contain low level controls which deal with control of the image capture process --- the A/D converter in image sensors, for example.

---

 Documentation/DocBook/media/v4l/controls.xml       |  101

+++++++++++++++++ .../DocBook/media/v4l/vidioc-g-ext-ctrls.xml |

    6 +
 drivers/media/video/v4l2-ctrls.c                   |   10 ++
 include/linux/videodev2.h                          |   10 ++
 4 files changed, 127 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/Documentation/DocBook/media/v4l/controls.xml index 3bc5ee8..69ede83 100644

Documentation/DocBook/media/v4l/controls.xml +11 -0
@@ -3356,6 +3356,107 @@ interface and may change in the future.</para>
 
       </table>
 
     </section>
 
+
+    <section id="image-source-controls">
+      <title>Image Source Control Reference</title>
+
+      <note>
+	<title>Experimental</title>
+
+	<para>This is an <link
+	linkend="experimental">experimental</link> interface and may
+	change in the future.</para>
+      </note>
Quoted 8 lines

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3374

Quoted 5 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+
+      <para>
+	The Image Source control class is intended for low-level
+	control of image source devices such as image sensors. The
+	devices feature an analogue to digital converter and a bus

Is the V4L2 documentation written in US or UK English ? US uses analog, UK uses analogue. Analog would be shorter in control names.

Both appear to be used, but the US English appears to be more commonly used. I guess it's mostly chosen by whatever happened to be used by the author of the patch. I prefer UK spelling which you might have noticed already. :-)

Quoted 5 lines
Quoted 2 lines

Yes I have. I haven't checked whether V4L2 prefers the UK or US spelling. I'll trust you on that.

I have checked and most seem to have used US spelling. If you wish me to change it, I can do that.

As you (and others) wish.

Quoted 93 lines
Quoted 92 lines
Quoted 88 lines

I remember there was a discussion on this topic years ago within the kernel community but I don't remember how it ended up with... LWN.net appears to remember better than I do, but by a quick check I can't find any definitive conclusion.

<URL:http://lwn.net/Articles/44262/>
<URL:http://lkml.org/lkml/2003/8/7/245>

Quoted 67 lines
Quoted 40 lines
Documentation/DocBook/media/v4l/controls.xml +18 -0
+	transmitter to transmit the image data out of the device.
+      </para>
+
+      <table pgwide="1" frame="none" id="image-source-control-id">
+      <title>Image Source Control IDs</title>
+
+      <tgroup cols="4">
+	<colspec colname="c1" colwidth="1*" />
+	<colspec colname="c2" colwidth="6*" />
+	<colspec colname="c3" colwidth="2*" />
+	<colspec colname="c4" colwidth="6*" />
+	<spanspec namest="c1" nameend="c2" spanname="id" />
+	<spanspec namest="c2" nameend="c4" spanname="descr" />
+	<thead>
+	  <row>
+	    <entry spanname="id" align="left">ID</entry>
+	    <entry align="left">Type</entry>
+	  </row><row rowsep="1"><entry spanname="descr"

align="left">Description</entry> + </row>

Documentation/DocBook/media/v4l/controls.xml +5 -0
+	</thead>
+	<tbody valign="top">
+	  <row><entry></entry></row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant></entry>

Documentation/DocBook/media/v4l/controls.xml +4 -0
+
 
  <entry>class</entry>
 
+	  </row>
+	  <row>
+	    <entry spanname="descr">The IMAGE_SOURCE class

descriptor.</entry> + </row>

Documentation/DocBook/media/v4l/controls.xml +2 -0
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_VBLANK</constant></entry

Quoted 1 line

+

<entry>integer</entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3410

Quoted 4 lines
Documentation/DocBook/media/v4l/controls.xml +4 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Vertical blanking. The idle
+	    preriod after every frame during which no image data is

s/preriod/period/

Quoted 13 lines
Documentation/DocBook/media/v4l/controls.xml +8 -0
+	    produced. The unit of vertical blanking is a line. Every
+	    line has length of the image width plus horizontal
+	    blanking at the pixel clock specified by struct
+	    v4l2_mbus_framefmt <xref linkend="v4l2-mbus-framefmt"
+	    />.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_HBLANK</constant></entry

Quoted 1 line

+

<entry>integer</entry>

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3423

Quoted 4 lines
Documentation/DocBook/media/v4l/controls.xml +4 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Horizontal blanking. The idle
+	    preriod after every line of image data during which no

s/preriod/period/

Quoted 12 lines

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3432

Quoted 10 lines
Documentation/DocBook/media/v4l/controls.xml +5 -0
+	    image data is produced. The unit of horizontal blanking is
+	    pixels.</entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_LINK_FREQ</constant></en
tr y> + <entry>integer menu</entry>

Documentation/DocBook/media/v4l/controls.xml +3 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Image source's data bus frequency.

What's the frequency unit ? Sample/second ?

Quoted 1 line

Hz --- that's the unit of frequency. I fixed that in the new version.

Is the user supposed to compute the pixel clock from this information ? That's what the text below seems to imply.

Quoted 8 lines
Quoted 4 lines

Apparently I have forgotten to update this in the new patchset. But yes, these factors do define it. The sensors' internal clock tree will be involved and calculation is non-trivial. This is why we also have the PIXEL_RATE control --- where I will refer to in the next patchset.

How is the sensor clock tree involved ? My understanding is that it will define the data bus frequency based on the sensor input clock, but the bus data rate shouldn't be influenced by the clock tree for a given bus frequency.

Uh, I was referring to the pixel array. On the CSI-2 receiver, there are also factors like data bus width, bits-per-pixel and lane count that affect the pixel rate on the bus. I don't think the user should be required to know about them.

Quoted 3 lines

Computing the pixel rate from the bus frequency isn't trivial and shouldn't be done by userspace if my understanding is correct. Documenting all this clearly would probably help :-)

The idea is that by defining all these factors one can query the real pixel rate from the pixel array. That pixel rate will be constant as long as all the above parameters are. Then blanking can be changed to lower the frame rate (taking the policy decisions at the same time).

I guess I could put it in a more clear way.

Quoted 30 lines
Quoted 30 lines
Quoted 29 lines
Quoted 22 lines
Quoted 13 lines
Quoted 13 lines
Documentation/DocBook/media/v4l/controls.xml +11 -0
+	    Together with the media bus pixel code, bus type (clock
+	    cycles per sample), the data bus frequency defines the
+	    pixel clock. <xref linkend="v4l2-mbus-framefmt" /> The
+	    frame rate can be calculated from the pixel clock, image
+	    width and height and horizontal and vertical blanking. The
+	    frame rate control is performed by selecting the desired
+	    horizontal and vertical blanking.
+	    </entry>
+	  </row>
+	  <row>
+	    <entry

spanname="id"><constant>V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN</constant>
</ en try> + <entry>integer</entry>

Quoted 8 lines

Documentation/DocBook/media/v4l/controls.xml interface and may change in the future.</para> · line 3450

Quoted 6 lines
Documentation/DocBook/media/v4l/controls.xml +6 -0
+	  </row>
+	  <row>
+	    <entry spanname="descr">Analogue gain is gain affecting
+	    all colour components in the pixel matrix. The gain
+	    operation is performed in the analogue domain before A/D
+	    conversion.

Should we define one gain per color component ?

Quoted 3 lines

I think that in the end we may need up to six analogue gains:

- Gain for all components

Many sensors that provide per-component gains also provide a global gain control that sets the four component gains. I'm not sure how (and if) we should handle that.

Quoted 7 lines
Quoted 3 lines

If it directly affects all of them, I don't think we should support it. But if it's independent of the colour-specific ones, then, sure, it should be supported.

It directly affects them. It's a shortcut. Maybe the R, G and B gain controls should then be put in a cluster, and if the user sets them to the same value the driver would optimize I2C communication by using the global gain control.

A cluster would be fine, I guess. But on some other hardware the all-component gain could be independent of the per-component ones.

...

Quoted 36 lines
Quoted 36 lines
Quoted 24 lines
Quoted 24 lines
Quoted 7 lines
Quoted 7 lines
Documentation/DocBook/media/v4l/controls.xml +0 -0
@@ -694,6 +700,9 @@ void v4l2_ctrl_fill(u32 id, const char **name,

enum

v4l2_ctrl_type *type, case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:

Documentation/DocBook/media/v4l/controls.xml +0 -0
 		*type = V4L2_CTRL_TYPE_MENU;
 		break;
Quoted 6 lines

Documentation/DocBook/media/v4l/controls.xml

Quoted 3 lines
Documentation/DocBook/media/v4l/controls.xml +3 -0
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:
+		*type = V4L2_CTRL_TYPE_INTEGER_MENU;
+		break;

Will this always be an integer menu control, or can you foresee cases where the range would be continuous ?

Good question. On some hardware this definitely is an integer menu, but hardware may exist where more selections would be available.

However, on e.g. the SMIA++ sensor the calculation of the clock tree values depends heavily on the selected link rate. Choosing a wrong link rate may yield to the clock tree calculation to fail. So the driver likely would need to enforce some rules which values are allowed. That might prove unfeasible --- already the PLL code in the SMIA++ driver is relatively complex.

Quoted 3 lines
Quoted 1 line

I don't see much benefit in being able to specify this freely.

For SMIA++, definitely not. For other sensors, I don't know.

At least one Aptina sensor had a clock tree which basically had a few dividers and a multiplier. The same restrictions apply.

Quoted 4 lines
Quoted 2 lines

AFAIR the conclusion was that controls may only have one type when the control framework was written.

Yes, but I'm not sure whether that's a good conclusion :-)

Quoted 7 lines
Quoted 5 lines

It allows you to assume a type for controls, whether that's good or not.

This could be one use case for that, but I don't really see much advantage in (attepmpting) to support fully free sensor link frequency configuration.

Who will then be responsible for creating the list of available frequencies ?

That would be the one who defines also the other board specific parameters such as the number of lanes. The link frequency has to fill several requirements, and some of that is policy whereas some is not.

Things to consider are system memory bus data rate, CSI-2 receiver's (or ISP's) memory access priority compared to other users, maximum pixel rate of the CSI-2 receiver (and also that of the ISP, if the CSI-2 receiver is part of it), sensor's external clock frequency and properties of the sensor clock tree (the frequency must be achievable using the available PLL divisors and multipliers) and at least on some boards, also system's EMC requirements.

I don't think the above list is exhaustive.

For example, on OMAP 3[67]xx based boards it could make sense to define data rates which can produce pixel rates close to 500 MHz and 250 MHz which correspond to the maximum speed of the CSI-2 receiver and the ISP (100 Mp/s) with two lanes (CSI-2 transfers 2 bits for every clock cycle).

One could also define the highest operating point to be less than that, which would likely have an effect to the desired link frequencies. 34xx has smaller maximum ISP data rate, so if you connect the same sensor to that you'll likely want to change the supported link rate(s).

Regards,

Signature · 2 lines
Sakari Ailus
[email protected]
#39 lore raw

Re: [RFC 08/17] v4l: Image source control class

In reply to Sakari Ailus

Hi Sakari,

Quoted 16 lines · Sakari Ailus
Quoted 8 lines
Quoted 8 lines
(quoted diff) +0 -0

b/drivers/media/video/v4l2-ctrls.c index 083bb79..da1ec52 100644

drivers/media/video/v4l2-ctrls.c +0 -0
@@ -606,6 +606,12 @@ const char *v4l2_ctrl_get_name(u32 id)
  	case V4L2_CID_FLASH_CHARGE:		return "Charge";
  	case V4L2_CID_FLASH_READY:		return "Ready to strobe";
 
Quoted 7 lines

drivers/media/video/v4l2-ctrls.c const char *v4l2_ctrl_get_name(u32 id) · line 613

Quoted 5 lines
drivers/media/video/v4l2-ctrls.c +5 -0
+	case V4L2_CID_IMAGE_SOURCE_CLASS:	return "Image source controls";
+	case V4L2_CID_IMAGE_SOURCE_VBLANK:	return "Vertical blanking";
+	case V4L2_CID_IMAGE_SOURCE_HBLANK:	return "Horizontal blanking";
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:	return "Link frequency";
+	case V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN: return "Analogue gain";

Please capitalize each word, as done for the other controls.

Quoted 5 lines

This isn't done for the flash controls either, have you noticed that?

Well, I guess I have to admit that they were added by myself. ;-)

I can fix this for the next patchset.

I don't want to be annoying (too much ;)) but the FLASH controls documentation is missing some <constant> tags in the text. Other classes use them for standard identifiers.

Regards,
Sylwester

#40 lore raw

Re: [RFC 08/17] v4l: Image source control class

Hi Sylwester,

Quoted 19 lines · Sylwester Nawrocki
Quoted 18 lines · Sakari Ailus
Quoted 8 lines
Quoted 8 lines
(quoted diff) +0 -0

b/drivers/media/video/v4l2-ctrls.c index 083bb79..da1ec52 100644

drivers/media/video/v4l2-ctrls.c +0 -0
@@ -606,6 +606,12 @@ const char *v4l2_ctrl_get_name(u32 id)
  	case V4L2_CID_FLASH_CHARGE:		return "Charge";
  	case V4L2_CID_FLASH_READY:		return "Ready to strobe";
 
Quoted 7 lines

drivers/media/video/v4l2-ctrls.c const char *v4l2_ctrl_get_name(u32 id) · line 613

Quoted 5 lines
drivers/media/video/v4l2-ctrls.c +5 -0
+	case V4L2_CID_IMAGE_SOURCE_CLASS:	return "Image source controls";
+	case V4L2_CID_IMAGE_SOURCE_VBLANK:	return "Vertical blanking";
+	case V4L2_CID_IMAGE_SOURCE_HBLANK:	return "Horizontal blanking";
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:	return "Link frequency";
+	case V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN: return "Analogue gain";

Please capitalize each word, as done for the other controls.

This isn't done for the flash controls either, have you noticed that?

Quoted 7 lines
Quoted 3 lines

Well, I guess I have to admit that they were added by myself. ;-)

I can fix this for the next patchset.

I don't want to be annoying (too much ;)) but the FLASH controls documentation is missing some <constant> tags in the text. Other classes use them for standard identifiers.

Thanks for letting me know --- that could be fixed with the flash timing control API, or unrelated to that. We should btw. continue discussion on that one. :-)

Speaking of things to do... The colour of the object to point and press V4L2_CID_DO_WHITE_BALANCE (or what was it called) to fix the white balance --- is that white, gray, something else or implementation dependent? I vaguely remember having seen some grayish plates being used for that but I'm definitely not sure. :-) Any idea?

Regards,

Signature · 2 lines
Sakari Ailus
[email protected]
#41 lore raw

Re: [RFC 08/17] v4l: Image source control class

Quoted 26 lines · Sakari Ailus

Hi Sylwester,

Quoted 23 lines · Sylwester Nawrocki
Quoted 21 lines · Sakari Ailus
Quoted 8 lines
Quoted 8 lines
(quoted diff) +0 -0

b/drivers/media/video/v4l2-ctrls.c index 083bb79..da1ec52 100644

drivers/media/video/v4l2-ctrls.c +0 -0
@@ -606,6 +606,12 @@ const char *v4l2_ctrl_get_name(u32 id)
   	case V4L2_CID_FLASH_CHARGE:		return "Charge";
   	case V4L2_CID_FLASH_READY:		return "Ready to strobe";
 
Quoted 7 lines

drivers/media/video/v4l2-ctrls.c const char *v4l2_ctrl_get_name(u32 id) · line 613

Quoted 5 lines
drivers/media/video/v4l2-ctrls.c +5 -0
+	case V4L2_CID_IMAGE_SOURCE_CLASS:	return "Image source controls";
+	case V4L2_CID_IMAGE_SOURCE_VBLANK:	return "Vertical blanking";
+	case V4L2_CID_IMAGE_SOURCE_HBLANK:	return "Horizontal blanking";
+	case V4L2_CID_IMAGE_SOURCE_LINK_FREQ:	return "Link frequency";
+	case V4L2_CID_IMAGE_SOURCE_ANALOGUE_GAIN: return "Analogue gain";

Please capitalize each word, as done for the other controls.

This isn't done for the flash controls either, have you noticed that?

Well, I guess I have to admit that they were added by myself. ;-)

I can fix this for the next patchset.

Quoted 7 lines
Quoted 3 lines

I don't want to be annoying (too much ;)) but the FLASH controls documentation is missing some<constant> tags in the text. Other classes use them for standard identifiers.

Thanks for letting me know --- that could be fixed with the flash timing control API, or unrelated to that. We should btw. continue discussion on that one. :-)

Sure, I remember having a patch for that style correction somewhere around.

Certainly the Flash topic needs continuation, I'll get back to it shortly. I just need to do some more research about it and it is not of really high priority on my side now. Plus I have temporarily been out of order for the last week..

I have just prepared an auto focus controls draft patch. I'll post it hopefully tonight to move things forward.

Quoted 5 lines

Speaking of things to do... The colour of the object to point and press V4L2_CID_DO_WHITE_BALANCE (or what was it called) to fix the white balance --- is that white, gray, something else or implementation dependent? I vaguely remember having seen some grayish plates being used for that but I'm definitely not sure. :-) Any idea?

As far as I know it should be always an object which is perceived as white. Something else don't seem to be terribly useful to set up white balance. Unfortunately I don't have much of experience with that yet.

--
Regards,
Sylwester

#42 lore raw

RFC 9/17 v4l: Add pad op for pipeline validation

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

smiapp_pad_ops.validate_pipeline is intended to validate the full pipeline which is implemented by the driver to which the subdev implementing this op belongs to. The validate_pipeline op must also call validate_pipeline on any external entity which is linked to its sink pads.

---
 include/media/v4l2-subdev.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
include/media/v4l2-subdev.h +1 -0
index 26eeaa4..a5ebe86 100644
@@ -470,6 +470,7 @@ struct v4l2_subdev_pad_ops {
 			     struct v4l2_subdev_selection *sel);
 	int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
 			     struct v4l2_subdev_selection *sel);
+	int (*validate_pipeline)(struct v4l2_subdev *sd);
 };
 
 struct v4l2_subdev_ops {
Signature · 1 line
1.7.2.5
#43 lore raw

Re: [RFC 09/17] v4l: Add pad op for pipeline validation

Hi Sakari,

Thanks for the patch.

Quoted 5 lines · On Tuesday 20 December 2011 21:28:01 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

smiapp_pad_ops.validate_pipeline is intended to validate the full pipeline which is implemented by the driver to which the subdev implementing this op belongs to.

Should this be documented in Documentation/video4linux/v4l2-framework.txt ?

Quoted 2 lines

The validate_pipeline op must also call validate_pipeline on any external entity which is linked to its sink pads.

I'm uncertain about this. Subdev drivers would then have to implement the pipeline walk logic, resulting in duplicate code. Our current situation isn't optimal either: walking the pipeline should be implemented in the media code. Would it suit your needs if the validate_pipeline operation was replaced by a validate_link operation, with a media_pipeline_validate() function in the media core to walk the pipeline and call validate_link in each pad (or maybe each sink pad) ?

Quoted 17 lines
---
 include/media/v4l2-subdev.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
include/media/v4l2-subdev.h +1 -0
index 26eeaa4..a5ebe86 100644
@@ -470,6 +470,7 @@ struct v4l2_subdev_pad_ops {
 			     struct v4l2_subdev_selection *sel);
 	int (*set_selection)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
 			     struct v4l2_subdev_selection *sel);
+	int (*validate_pipeline)(struct v4l2_subdev *sd);
 };
 
 struct v4l2_subdev_ops {
Signature · 3 lines
Regards,

Laurent Pinchart
#44 lore raw

Re: [RFC 09/17] v4l: Add pad op for pipeline validation

Hi Laurent,

Thanks for the review!!

Quoted 12 lines · Laurent Pinchart
Quoted 5 lines · On Tuesday 20 December 2011 21:28:01 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

smiapp_pad_ops.validate_pipeline is intended to validate the full pipeline which is implemented by the driver to which the subdev implementing this op belongs to.

Should this be documented in Documentation/video4linux/v4l2-framework.txt ?

Quoted 2 lines

The validate_pipeline op must also call validate_pipeline on any external entity which is linked to its sink pads.

Quoted 7 lines

I'm uncertain about this. Subdev drivers would then have to implement the pipeline walk logic, resulting in duplicate code. Our current situation isn't optimal either: walking the pipeline should be implemented in the media code. Would it suit your needs if the validate_pipeline operation was replaced by a validate_link operation, with a media_pipeline_validate() function in the media core to walk the pipeline and call validate_link in each pad (or maybe each sink pad) ?

Albeit I don't see the pipeline checking a big problem in the subdev drivers, that does seem like a viable alternative --- it's definitely more generic. Any benefit of that is directly bound to the existence of generic pipeline validation function, which definitely shouldn't be too difficult to write.

It is also true that in practice, I assume, considering the pipeline validation inside subdev drivers, the SMIA++ driver is almost as complex any sensor driver will get in the near future. But once a practice has been established it's difficult to change that.

I'm for validate_link() op.

I assume that in the implementation the Media controller framework would walk the pipeline and call entity specific link_validate() ops. We already have link_setup() op there. Those would, in turn, check that the link requirements are fulfilled. How does that sound like to you?

Regards,

Signature · 2 lines
Sakari Ailus
[email protected]
#45 lore raw

Re: [RFC 09/17] v4l: Add pad op for pipeline validation

Hi Sakari,

Quoted 33 lines · On Sunday 08 January 2012 00:28:40 Sakari Ailus wrote:
Quoted 13 lines · Laurent Pinchart
Quoted 5 lines · On Tuesday 20 December 2011 21:28:01 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

smiapp_pad_ops.validate_pipeline is intended to validate the full pipeline which is implemented by the driver to which the subdev implementing this op belongs to.

Should this be documented in Documentation/video4linux/v4l2-framework.txt ?

Quoted 2 lines

The validate_pipeline op must also call validate_pipeline on any external entity which is linked to its sink pads.

Quoted 7 lines

I'm uncertain about this. Subdev drivers would then have to implement the pipeline walk logic, resulting in duplicate code. Our current situation isn't optimal either: walking the pipeline should be implemented in the media code. Would it suit your needs if the validate_pipeline operation was replaced by a validate_link operation, with a media_pipeline_validate() function in the media core to walk the pipeline and call validate_link in each pad (or maybe each sink pad) ?

Albeit I don't see the pipeline checking a big problem in the subdev drivers, that does seem like a viable alternative --- it's definitely more generic. Any benefit of that is directly bound to the existence of generic pipeline validation function, which definitely shouldn't be too difficult to write.

It is also true that in practice, I assume, considering the pipeline validation inside subdev drivers, the SMIA++ driver is almost as complex any sensor driver will get in the near future. But once a practice has been established it's difficult to change that.

Quoted 6 lines

I'm for validate_link() op.

I assume that in the implementation the Media controller framework would walk the pipeline and call entity specific link_validate() ops. We already have link_setup() op there. Those would, in turn, check that the link requirements are fulfilled. How does that sound like to you?

That sounds good to me. If the operation isn't implemented, the core should just make sure that code, width and height are identical on the two ends of the link. That will be the usual requirement, checking it in the core will make drivers simpler.

Signature · 3 lines
Regards,

Laurent Pinchart
#46 lore raw

RFC 10/17 omap3: add definition for CONTROL_CAMERA_PHY_CTRL

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

This register is available only in OMAP3630.

The original patch was submitted by Vimarsh Zutshi.

---
 arch/arm/mach-omap2/control.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/control.h +1 -0
index d4ef75d..6a26a0d 100644
@@ -183,6 +183,7 @@
 #define OMAP3630_CONTROL_FUSE_OPP120_VDD1       (OMAP2_CONTROL_GENERAL + 0x0120)
 #define OMAP3630_CONTROL_FUSE_OPP50_VDD2        (OMAP2_CONTROL_GENERAL + 0x0128)
 #define OMAP3630_CONTROL_FUSE_OPP100_VDD2       (OMAP2_CONTROL_GENERAL + 0x012C)
+#define OMAP3630_CONTROL_CAMERA_PHY_CTRL	(OMAP2_CONTROL_GENERAL + 0x02f0)
 
 /* OMAP44xx control efuse offsets */
 #define OMAP44XX_CONTROL_FUSE_IVA_OPP50		0x22C
Signature · 1 line
1.7.2.5
#47 lore raw

RFC 11/17 omap3isp: Implement validate_pipeline

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

Validate pipeline of any external entity connected to the ISP driver. The validation of the pipeline for the part that involves links inside the domain of another driver must be done by that very driver.

---
 drivers/media/video/omap3isp/ispvideo.c |   12 ++++++++++++
 1 files changed, 12 insertions(+), 0 deletions(-)
drivers/media/video/omap3isp/ispvideo.c +12 -0
index f229057..0568234 100644
@@ -355,6 +355,18 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
 		    fmt_source.format.height != fmt_sink.format.height)
 			return -EPIPE;
 
+		if (subdev->host_priv) {
+			/*
+			 * host_priv != NULL: this is a sensor. Issue
+			 * validate_pipeline. We're at our end of the
+			 * pipeline so we quit now.
+			 */
+			ret = v4l2_subdev_call(subdev, pad, validate_pipeline);
+			if (ret < 0 && ret != -ENOIOCTLCMD)
+				return -EPIPE;
+			break;
+		}
+
 		if (shifter_link) {
 			unsigned int parallel_shift = 0;
 			if (isp->isp_ccdc.input == CCDC_INPUT_PARALLEL) {
Signature · 1 line
1.7.2.5
#48 lore raw

RFC 12/17 omap3isp: Add lane configuration to platform data

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

Add lane configuration (order of clock and data lane) to platform data on both CCP2 and CSI-2.

---
 drivers/media/video/omap3isp/ispcsiphy.h |   15 ++-------------
 include/media/omap3isp.h                 |   15 +++++++++++++++
 2 files changed, 17 insertions(+), 13 deletions(-)
drivers/media/video/omap3isp/ispcsiphy.h +2 -13
index 9596dc6..e93a661 100644
@@ -27,22 +27,11 @@
 #ifndef OMAP3_ISP_CSI_PHY_H
 #define OMAP3_ISP_CSI_PHY_H
 
+#include <media/omap3isp.h>
+
 struct isp_csi2_device;
 struct regulator;
 
-struct csiphy_lane {
-	u8 pos;
-	u8 pol;
-};
-
-#define ISP_CSIPHY2_NUM_DATA_LANES	2
-#define ISP_CSIPHY1_NUM_DATA_LANES	1
-
-struct isp_csiphy_lanes_cfg {
-	struct csiphy_lane data[ISP_CSIPHY2_NUM_DATA_LANES];
-	struct csiphy_lane clk;
-};
-
 struct isp_csiphy_dphy_cfg {
 	u8 ths_term;
 	u8 ths_settle;
include/media/omap3isp.h +15 -0
index e917b1d..8fe0bdf 100644
@@ -86,6 +86,19 @@ enum {
 	ISP_CCP2_MODE_CCP2 = 1,
 };
 
+struct csiphy_lane {
+	u8 pos;
+	u8 pol;
+};
+
+#define ISP_CSIPHY2_NUM_DATA_LANES	2
+#define ISP_CSIPHY1_NUM_DATA_LANES	1
+
+struct isp_csiphy_lanes_cfg {
+	struct csiphy_lane data[ISP_CSIPHY2_NUM_DATA_LANES];
+	struct csiphy_lane clk;
+};
+
 /**
  * struct isp_ccp2_platform_data - CCP2 interface platform data
  * @strobe_clk_pol: Strobe/clock polarity
@@ -105,6 +118,7 @@ struct isp_ccp2_platform_data {
 	unsigned int ccp2_mode:1;
 	unsigned int phy_layer:1;
 	unsigned int vpclk_div:2;
+	struct isp_csiphy_lanes_cfg *lanecfg;
 };
 
 /**
@@ -115,6 +129,7 @@ struct isp_ccp2_platform_data {
 struct isp_csi2_platform_data {
 	unsigned crc:1;
 	unsigned vpclk_div:2;
+	struct isp_csiphy_lanes_cfg *lanecfg;
 };
 
 struct isp_subdev_i2c_board_info {
Signature · 1 line
1.7.2.5
#49 lore raw

Re: [RFC 12/17] omap3isp: Add lane configuration to platform data

Hi Sakari,

Thanks for the patch.

Quoted 50 lines · On Tuesday 20 December 2011 21:28:04 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add lane configuration (order of clock and data lane) to platform data on both CCP2 and CSI-2.

---
 drivers/media/video/omap3isp/ispcsiphy.h |   15 ++-------------
 include/media/omap3isp.h                 |   15 +++++++++++++++
 2 files changed, 17 insertions(+), 13 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispcsiphy.h index 9596dc6..e93a661 100644

drivers/media/video/omap3isp/ispcsiphy.h +2 -13
@@ -27,22 +27,11 @@
 #ifndef OMAP3_ISP_CSI_PHY_H
 #define OMAP3_ISP_CSI_PHY_H
 
+#include <media/omap3isp.h>
+
 struct isp_csi2_device;
 struct regulator;
 
-struct csiphy_lane {
-	u8 pos;
-	u8 pol;
-};
-
-#define ISP_CSIPHY2_NUM_DATA_LANES	2
-#define ISP_CSIPHY1_NUM_DATA_LANES	1
-
-struct isp_csiphy_lanes_cfg {
-	struct csiphy_lane data[ISP_CSIPHY2_NUM_DATA_LANES];
-	struct csiphy_lane clk;
-};
-
 struct isp_csiphy_dphy_cfg {
 	u8 ths_term;
 	u8 ths_settle;
include/media/omap3isp.h +2 -0
index e917b1d..8fe0bdf 100644
@@ -86,6 +86,19 @@ enum {
 	ISP_CCP2_MODE_CCP2 = 1,
 };
 
+struct csiphy_lane {
+	u8 pos;

include/media/omap3isp.h enum { · line 100

Quoted 10 lines
include/media/omap3isp.h +10 -0
+	u8 pol;
+};
+
+#define ISP_CSIPHY2_NUM_DATA_LANES	2
+#define ISP_CSIPHY1_NUM_DATA_LANES	1
+
+struct isp_csiphy_lanes_cfg {
+	struct csiphy_lane data[ISP_CSIPHY2_NUM_DATA_LANES];
+	struct csiphy_lane clk;
+};

Could you please document the two structures using kerneldoc ?

include/media/omap3isp.h struct isp_ccp2_platform_data { · line 121

Quoted 9 lines
include/media/omap3isp.h +2 -0
+
 /**
  * struct isp_ccp2_platform_data - CCP2 interface platform data
  * @strobe_clk_pol: Strobe/clock polarity
@@ -105,6 +118,7 @@ struct isp_ccp2_platform_data {
 	unsigned int ccp2_mode:1;
 	unsigned int phy_layer:1;
 	unsigned int vpclk_div:2;
+	struct isp_csiphy_lanes_cfg *lanecfg;

Lane configuration is mandatory, what about embedding struct isp_csiphy_lanes_cfg inside struct isp_ccp2_platform instead of having a pointer ?

include/media/omap3isp.h struct isp_ccp2_platform_data { · line 132

Quoted 8 lines
include/media/omap3isp.h +1 -0
 };
 
 /**
@@ -115,6 +129,7 @@ struct isp_ccp2_platform_data {
 struct isp_csi2_platform_data {
 	unsigned crc:1;
 	unsigned vpclk_div:2;
+	struct isp_csiphy_lanes_cfg *lanecfg;

Same here.

Quoted 3 lines
include/media/omap3isp.h +0 -0
 };
 
 struct isp_subdev_i2c_board_info {
Signature · 3 lines
Regards,

Laurent Pinchart
#50 lore raw

Re: [RFC 12/17] omap3isp: Add lane configuration to platform data

Hi Laurent,

Quoted 49 lines · Laurent Pinchart
Quoted 48 lines · On Tuesday 20 December 2011 21:28:04 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Add lane configuration (order of clock and data lane) to platform data on both CCP2 and CSI-2.

---
 drivers/media/video/omap3isp/ispcsiphy.h |   15 ++-------------
 include/media/omap3isp.h                 |   15 +++++++++++++++
 2 files changed, 17 insertions(+), 13 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispcsiphy.h index 9596dc6..e93a661 100644

drivers/media/video/omap3isp/ispcsiphy.h +2 -13
@@ -27,22 +27,11 @@
 #ifndef OMAP3_ISP_CSI_PHY_H
 #define OMAP3_ISP_CSI_PHY_H
 
+#include <media/omap3isp.h>
+
 struct isp_csi2_device;
 struct regulator;
 
-struct csiphy_lane {
-	u8 pos;
-	u8 pol;
-};
-
-#define ISP_CSIPHY2_NUM_DATA_LANES	2
-#define ISP_CSIPHY1_NUM_DATA_LANES	1
-
-struct isp_csiphy_lanes_cfg {
-	struct csiphy_lane data[ISP_CSIPHY2_NUM_DATA_LANES];
-	struct csiphy_lane clk;
-};
-
 struct isp_csiphy_dphy_cfg {
 	u8 ths_term;
 	u8 ths_settle;
include/media/omap3isp.h +0 -0
index e917b1d..8fe0bdf 100644
@@ -86,6 +86,19 @@ enum {
 	ISP_CCP2_MODE_CCP2 = 1,
 };
 
Quoted 14 lines

include/media/omap3isp.h enum { · line 100

Quoted 12 lines
include/media/omap3isp.h +12 -0
+struct csiphy_lane {
+	u8 pos;
+	u8 pol;
+};
+
+#define ISP_CSIPHY2_NUM_DATA_LANES	2
+#define ISP_CSIPHY1_NUM_DATA_LANES	1
+
+struct isp_csiphy_lanes_cfg {
+	struct csiphy_lane data[ISP_CSIPHY2_NUM_DATA_LANES];
+	struct csiphy_lane clk;
+};

Could you please document the two structures using kerneldoc ?

Done.

Quoted 5 lines
Quoted 5 lines
include/media/omap3isp.h +1 -0
+
 /**
  * struct isp_ccp2_platform_data - CCP2 interface platform data
  * @strobe_clk_pol: Strobe/clock polarity
@@ -105,6 +118,7 @@ struct isp_ccp2_platform_data {
Quoted 8 lines

include/media/omap3isp.h struct isp_ccp2_platform_data { · line 121

Quoted 4 lines
include/media/omap3isp.h +1 -0
 	unsigned int ccp2_mode:1;
 	unsigned int phy_layer:1;
 	unsigned int vpclk_div:2;
+	struct isp_csiphy_lanes_cfg *lanecfg;

Lane configuration is mandatory, what about embedding struct isp_csiphy_lanes_cfg inside struct isp_ccp2_platform instead of having a pointer ?

Done.

Quoted 10 lines

include/media/omap3isp.h struct isp_ccp2_platform_data { · line 132

Quoted 8 lines
include/media/omap3isp.h +1 -0
 };
 
 /**
@@ -115,6 +129,7 @@ struct isp_ccp2_platform_data {
 struct isp_csi2_platform_data {
 	unsigned crc:1;
 	unsigned vpclk_div:2;
+	struct isp_csiphy_lanes_cfg *lanecfg;

Same here.

Ditto.

Quoted 4 lines
Quoted 3 lines
include/media/omap3isp.h +0 -0
 };
 
 struct isp_subdev_i2c_board_info {
Signature · 2 lines
Sakari Ailus
[email protected]
#51 lore raw

RFC 13/17 omap3isp: Configure CSI-2 phy based on platform data

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

Configure CSI-2 phy based on platform data in the ISP driver rather than in platform code.

---
 drivers/media/video/omap3isp/isp.c       |   38 ++++++++++++--
 drivers/media/video/omap3isp/isp.h       |    3 -
 drivers/media/video/omap3isp/ispcsiphy.c |   83 ++++++++++++++++++++++++++----
 drivers/media/video/omap3isp/ispcsiphy.h |    4 ++
 4 files changed, 111 insertions(+), 17 deletions(-)
drivers/media/video/omap3isp/isp.c +34 -4
index b818cac..6020fd7 100644
@@ -737,7 +737,7 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
 	struct isp_device *isp = pipe->output->isp;
 	struct media_entity *entity;
 	struct media_pad *pad;
-	struct v4l2_subdev *subdev;
+	struct v4l2_subdev *subdev = NULL, *prev_subdev;
 	unsigned long flags;
 	int ret;
 
@@ -759,11 +759,41 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
 			break;
 
 		entity = pad->entity;
+		prev_subdev = subdev;
 		subdev = media_entity_to_v4l2_subdev(entity);
 
-		ret = v4l2_subdev_call(subdev, video, s_stream, mode);
-		if (ret < 0 && ret != -ENOIOCTLCMD)
-			return ret;
+		/* Configure CSI-2 receiver based on sensor format. */
+		if (prev_subdev == &isp->isp_csi2a.subdev
+		    || prev_subdev == &isp->isp_csi2c.subdev) {
+			struct v4l2_subdev_format fmt;
+
+			fmt.pad = pad->index;
+			fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+			ret = v4l2_subdev_call(subdev, pad, get_fmt,
+					       NULL, &fmt);
+			if (ret < 0)
+				return -EPIPE;
+
+			ret = omap3isp_csiphy_config(
+				isp, prev_subdev, subdev,
+				&fmt.format);
+			if (ret < 0)
+				return -EPIPE;
+
+			/* Start CSI-2 after configuration. */
+			ret = v4l2_subdev_call(prev_subdev, video,
+					       s_stream, mode);
+			if (ret < 0 && ret != -ENOIOCTLCMD)
+				return ret;
+		}
+
+		/* Start any other subdev except the CSI-2 receivers. */
+		if (subdev != &isp->isp_csi2a.subdev
+		    && subdev != &isp->isp_csi2c.subdev) {
+			ret = v4l2_subdev_call(subdev, video, s_stream, mode);
+			if (ret < 0 && ret != -ENOIOCTLCMD)
+				return ret;
+		}
 
 		if (subdev == &isp->isp_ccdc.subdev) {
 			v4l2_subdev_call(&isp->isp_aewb.subdev, video,
drivers/media/video/omap3isp/isp.h +0 -3
index 705946e..c5935ae 100644
@@ -126,9 +126,6 @@ struct isp_reg {
 
 struct isp_platform_callback {
 	u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel);
-	int (*csiphy_config)(struct isp_csiphy *phy,
-			     struct isp_csiphy_dphy_cfg *dphy,
-			     struct isp_csiphy_lanes_cfg *lanes);
 	void (*set_pixel_clock)(struct isp_device *isp, unsigned int pixelclk);
 };
 
drivers/media/video/omap3isp/ispcsiphy.c +73 -10

112 lines not on this page · raw message

drivers/media/video/omap3isp/ispcsiphy.h +4 -0
index e93a661..9f93222 100644
@@ -56,6 +56,10 @@ struct isp_csiphy {
 	struct isp_csiphy_dphy_cfg dphy;
 };
 
+int omap3isp_csiphy_config(struct isp_device *isp,
+			   struct v4l2_subdev *csi2_subdev,
+			   struct v4l2_subdev *sensor,
+			   struct v4l2_mbus_framefmt *fmt);
 int omap3isp_csiphy_acquire(struct isp_csiphy *phy);
 void omap3isp_csiphy_release(struct isp_csiphy *phy);
 int omap3isp_csiphy_init(struct isp_device *isp);
Signature · 1 line
1.7.2.5
#52 lore raw

Re: [RFC 13/17] omap3isp: Configure CSI-2 phy based on platform data

Hi Sakari,

Thanks for the patch.

Quoted 58 lines · On Tuesday 20 December 2011 21:28:05 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Configure CSI-2 phy based on platform data in the ISP driver rather than in platform code.

---
 drivers/media/video/omap3isp/isp.c       |   38 ++++++++++++--
 drivers/media/video/omap3isp/isp.h       |    3 -
 drivers/media/video/omap3isp/ispcsiphy.c |   83 +++++++++++++++++++++++----
 drivers/media/video/omap3isp/ispcsiphy.h |    4 ++
 4 files changed, 111 insertions(+), 17 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/isp.c index b818cac..6020fd7 100644

drivers/media/video/omap3isp/isp.c +24 -4
@@ -737,7 +737,7 @@ static int isp_pipeline_enable(struct isp_pipeline
 *pipe, struct isp_device *isp = pipe->output->isp;
 	struct media_entity *entity;
 	struct media_pad *pad;
-	struct v4l2_subdev *subdev;
+	struct v4l2_subdev *subdev = NULL, *prev_subdev;
 	unsigned long flags;
 	int ret;
 
@@ -759,11 +759,41 @@ static int isp_pipeline_enable(struct isp_pipeline
 *pipe, break;
 
 		entity = pad->entity;
+		prev_subdev = subdev;
 		subdev = media_entity_to_v4l2_subdev(entity);
 
-		ret = v4l2_subdev_call(subdev, video, s_stream, mode);
-		if (ret < 0 && ret != -ENOIOCTLCMD)
-			return ret;
+		/* Configure CSI-2 receiver based on sensor format. */
+		if (prev_subdev == &isp->isp_csi2a.subdev
+		    || prev_subdev == &isp->isp_csi2c.subdev) {
+			struct v4l2_subdev_format fmt;
+
+			fmt.pad = pad->index;
+			fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+			ret = v4l2_subdev_call(subdev, pad, get_fmt,
+					       NULL, &fmt);
+			if (ret < 0)
+				return -EPIPE;
+
+			ret = omap3isp_csiphy_config(
+				isp, prev_subdev, subdev,
+				&fmt.format);
+			if (ret < 0)
+				return -EPIPE;
+
+			/* Start CSI-2 after configuration. */
+			ret = v4l2_subdev_call(prev_subdev, video,
+					       s_stream, mode);
+			if (ret < 0 && ret != -ENOIOCTLCMD)

drivers/media/video/omap3isp/isp.c static int isp_pipeline_enable(struct isp_pipeline · line 796

Quoted 10 lines
drivers/media/video/omap3isp/isp.c +10 -0
+				return ret;
+		}
+
+		/* Start any other subdev except the CSI-2 receivers. */
+		if (subdev != &isp->isp_csi2a.subdev
+		    && subdev != &isp->isp_csi2c.subdev) {
+			ret = v4l2_subdev_call(subdev, video, s_stream, mode);
+			if (ret < 0 && ret != -ENOIOCTLCMD)
+				return ret;
+		}

What about moving this to the CSI2 s_stream subdev operation ?

Quoted 22 lines
drivers/media/video/omap3isp/isp.c +0 -0
 		if (subdev == &isp->isp_ccdc.subdev) {
 			v4l2_subdev_call(&isp->isp_aewb.subdev, video,
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/isp.h index 705946e..c5935ae 100644

drivers/media/video/omap3isp/isp.h +0 -3
@@ -126,9 +126,6 @@ struct isp_reg {
 
 struct isp_platform_callback {
 	u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel);
-	int (*csiphy_config)(struct isp_csiphy *phy,
-			     struct isp_csiphy_dphy_cfg *dphy,
-			     struct isp_csiphy_lanes_cfg *lanes);
 	void (*set_pixel_clock)(struct isp_device *isp, unsigned int pixelclk);
 };
 
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispcsiphy.c index 5be37ce..f027ece 100644

drivers/media/video/omap3isp/ispcsiphy.c line 32

Quoted 5 lines
drivers/media/video/omap3isp/ispcsiphy.c +2 -0
@@ -28,6 +28,8 @@
 #include <linux/device.h>
 #include <linux/regulator/consumer.h>
 
+#include "../../../../arch/arm/mach-omap2/control.h"
+

#include <mach/control.h>

(untested) ?

Quoted 26 lines
drivers/media/video/omap3isp/ispcsiphy.c +15 -3
 #include "isp.h"
 #include "ispreg.h"
 #include "ispcsiphy.h"
@@ -138,15 +140,78 @@ static void csiphy_dphy_config(struct isp_csiphy
 *phy) isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG1);
 }
 
-static int csiphy_config(struct isp_csiphy *phy,
-			 struct isp_csiphy_dphy_cfg *dphy,
-			 struct isp_csiphy_lanes_cfg *lanes)
+/*
+ * TCLK values are OK at their reset values
+ */
+#define TCLK_TERM	0
+#define TCLK_MISS	1
+#define TCLK_SETTLE	14
+
+int omap3isp_csiphy_config(struct isp_device *isp,
+			   struct v4l2_subdev *csi2_subdev,
+			   struct v4l2_subdev *sensor,
+			   struct v4l2_mbus_framefmt *sensor_fmt)
 {
+	struct isp_v4l2_subdevs_group *subdevs = sensor->host_priv;
+	struct isp_csi2_device *csi2 = v4l2_get_subdevdata(csi2_subdev);
+	struct isp_csiphy_dphy_cfg csi2phy;
+	int csi2_ddrclk_khz;

drivers/media/video/omap3isp/ispcsiphy.c static void csiphy_dphy_config(struct isp_csiphy · line 168

Quoted 10 lines
drivers/media/video/omap3isp/ispcsiphy.c +8 -0
+	struct isp_csiphy_lanes_cfg *lanes;
 	unsigned int used_lanes = 0;
 	unsigned int i;
+	u32 cam_phy_ctrl;
+
+	if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1
+	    || subdevs->interface == ISP_INTERFACE_CCP2B_PHY2)
+		lanes = subdevs->bus.ccp2.lanecfg;
+	else
+		lanes = subdevs->bus.csi2.lanecfg;

Shouldn't lane configuration be retrieved from the sensor instead ? Sensors could use different lane configuration depending on the mode. This could also be implemented later when needed, but I don't think it would be too difficult to get it right now.

Quoted 19 lines
drivers/media/video/omap3isp/ispcsiphy.c +19 -0
+
+	if (!lanes) {
+		dev_err(isp->dev, "no lane configuration\n");
+		return -EINVAL;
+	}
+
+	cam_phy_ctrl = omap_readl(
+		OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL);
+	/*
+	 * SCM.CONTROL_CAMERA_PHY_CTRL
+	 * - bit[4]    : CSIPHY1 data sent to CSIB
+	 * - bit [3:2] : CSIPHY1 config: 00 d-phy, 01/10 ccp2
+	 * - bit [1:0] : CSIPHY2 config: 00 d-phy, 01/10 ccp2
+	 */
+	if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1)
+		cam_phy_ctrl |= 1 << 2;
+	else if (subdevs->interface == ISP_INTERFACE_CSI2C_PHY1)
+		cam_phy_ctrl &= 1 << 2;
+

drivers/media/video/omap3isp/ispcsiphy.c static void csiphy_dphy_config(struct isp_csiphy *phy) · line 197

Quoted 10 lines
drivers/media/video/omap3isp/ispcsiphy.c +10 -0
+	if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY2)
+		cam_phy_ctrl |= 1;
+	else if (subdevs->interface == ISP_INTERFACE_CSI2A_PHY2)
+		cam_phy_ctrl &= 1;
+
+	/* FIXME: Do 34xx / 35xx require something here? */
+	if (cpu_is_omap3630())
+		omap_writel(cam_phy_ctrl,
+			    OMAP343X_CTRL_BASE
+			    + OMAP3630_CONTROL_CAMERA_PHY_CTRL);

You use cam_phy_ctrl inside the if statement only, you can move its computation there.

Quoted 60 lines
drivers/media/video/omap3isp/ispcsiphy.c +19 -7
+
+	csi2_ddrclk_khz = sensor_fmt->pixelrate
+		/ (2 * csi2->phy->num_data_lanes)
+		* omap3isp_video_format_info(sensor_fmt->code)->bpp;
+
+	/*
+	 * THS_TERM: Programmed value = ceil(12.5 ns/DDRClk period) - 1.
+	 * THS_SETTLE: Programmed value = ceil(90 ns/DDRClk period) + 3.
+	 */
+	csi2phy.ths_term = DIV_ROUND_UP(25 * csi2_ddrclk_khz, 2000000) - 1;
+	csi2phy.ths_settle = DIV_ROUND_UP(90 * csi2_ddrclk_khz, 1000000) + 3;
+	csi2phy.tclk_term = TCLK_TERM;
+	csi2phy.tclk_miss = TCLK_MISS;
+	csi2phy.tclk_settle = TCLK_SETTLE;
 
 	/* Clock and data lanes verification */
-	for (i = 0; i < phy->num_data_lanes; i++) {
+	for (i = 0; i < csi2->phy->num_data_lanes; i++) {
 		if (lanes->data[i].pol > 1 || lanes->data[i].pos > 3)
 			return -EINVAL;
 
@@ -162,10 +227,10 @@ static int csiphy_config(struct isp_csiphy *phy,
 	if (lanes->clk.pos == 0 || used_lanes & (1 << lanes->clk.pos))
 		return -EINVAL;
 
-	mutex_lock(&phy->mutex);
-	phy->dphy = *dphy;
-	phy->lanes = *lanes;
-	mutex_unlock(&phy->mutex);
+	mutex_lock(&csi2->phy->mutex);
+	csi2->phy->dphy = csi2phy;
+	csi2->phy->lanes = *lanes;
+	mutex_unlock(&csi2->phy->mutex);
 
 	return 0;
 }
@@ -225,8 +290,6 @@ int omap3isp_csiphy_init(struct isp_device *isp)
 	struct isp_csiphy *phy1 = &isp->isp_csiphy1;
 	struct isp_csiphy *phy2 = &isp->isp_csiphy2;
 
-	isp->platform_cb.csiphy_config = csiphy_config;
-
 	phy2->isp = isp;
 	phy2->csi2 = &isp->isp_csi2a;
 	phy2->num_data_lanes = ISP_CSIPHY2_NUM_DATA_LANES;
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispcsiphy.h index e93a661..9f93222 100644

drivers/media/video/omap3isp/ispcsiphy.h +4 -0
@@ -56,6 +56,10 @@ struct isp_csiphy {
 	struct isp_csiphy_dphy_cfg dphy;
 };
 
+int omap3isp_csiphy_config(struct isp_device *isp,
+			   struct v4l2_subdev *csi2_subdev,
+			   struct v4l2_subdev *sensor,
+			   struct v4l2_mbus_framefmt *fmt);
 int omap3isp_csiphy_acquire(struct isp_csiphy *phy);
 void omap3isp_csiphy_release(struct isp_csiphy *phy);
 int omap3isp_csiphy_init(struct isp_device *isp);
Signature · 3 lines
Regards,

Laurent Pinchart
#53 lore raw

Re: [RFC 13/17] omap3isp: Configure CSI-2 phy based on platform data

Hi Laurent,

Thanks for the review!!!

Quoted 63 lines · Laurent Pinchart
Quoted 62 lines · On Tuesday 20 December 2011 21:28:05 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Configure CSI-2 phy based on platform data in the ISP driver rather than in platform code.

---
 drivers/media/video/omap3isp/isp.c       |   38 ++++++++++++--
 drivers/media/video/omap3isp/isp.h       |    3 -
 drivers/media/video/omap3isp/ispcsiphy.c |   83 +++++++++++++++++++++++----
 drivers/media/video/omap3isp/ispcsiphy.h |    4 ++
 4 files changed, 111 insertions(+), 17 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/isp.c index b818cac..6020fd7 100644

drivers/media/video/omap3isp/isp.c +28 -4
@@ -737,7 +737,7 @@ static int isp_pipeline_enable(struct isp_pipeline
 *pipe, struct isp_device *isp = pipe->output->isp;
 	struct media_entity *entity;
 	struct media_pad *pad;
-	struct v4l2_subdev *subdev;
+	struct v4l2_subdev *subdev = NULL, *prev_subdev;
 	unsigned long flags;
 	int ret;
 
@@ -759,11 +759,41 @@ static int isp_pipeline_enable(struct isp_pipeline
 *pipe, break;
 
 		entity = pad->entity;
+		prev_subdev = subdev;
 		subdev = media_entity_to_v4l2_subdev(entity);
 
-		ret = v4l2_subdev_call(subdev, video, s_stream, mode);
-		if (ret < 0 && ret != -ENOIOCTLCMD)
-			return ret;
+		/* Configure CSI-2 receiver based on sensor format. */
+		if (prev_subdev == &isp->isp_csi2a.subdev
+		    || prev_subdev == &isp->isp_csi2c.subdev) {
+			struct v4l2_subdev_format fmt;
+
+			fmt.pad = pad->index;
+			fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+			ret = v4l2_subdev_call(subdev, pad, get_fmt,
+					       NULL, &fmt);
+			if (ret < 0)
+				return -EPIPE;
+
+			ret = omap3isp_csiphy_config(
+				isp, prev_subdev, subdev,
+				&fmt.format);
+			if (ret < 0)
+				return -EPIPE;
+
+			/* Start CSI-2 after configuration. */
+			ret = v4l2_subdev_call(prev_subdev, video,
+					       s_stream, mode);
+			if (ret < 0 && ret != -ENOIOCTLCMD)
+				return ret;
+		}
+
+		/* Start any other subdev except the CSI-2 receivers. */
Quoted 8 lines

drivers/media/video/omap3isp/isp.c static int isp_pipeline_enable(struct isp_pipeline *pipe, · line 796

Quoted 6 lines
drivers/media/video/omap3isp/isp.c +6 -0
+		if (subdev != &isp->isp_csi2a.subdev
+		    && subdev != &isp->isp_csi2c.subdev) {
+			ret = v4l2_subdev_call(subdev, video, s_stream, mode);
+			if (ret < 0 && ret != -ENOIOCTLCMD)
+				return ret;
+		}

What about moving this to the CSI2 s_stream subdev operation ?

Done.

Quoted 25 lines
Quoted 25 lines
drivers/media/video/omap3isp/isp.c +0 -0
 		if (subdev == &isp->isp_ccdc.subdev) {
 			v4l2_subdev_call(&isp->isp_aewb.subdev, video,
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/isp.h index 705946e..c5935ae 100644

drivers/media/video/omap3isp/isp.h +0 -3
@@ -126,9 +126,6 @@ struct isp_reg {
 
 struct isp_platform_callback {
 	u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel);
-	int (*csiphy_config)(struct isp_csiphy *phy,
-			     struct isp_csiphy_dphy_cfg *dphy,
-			     struct isp_csiphy_lanes_cfg *lanes);
 	void (*set_pixel_clock)(struct isp_device *isp, unsigned int pixelclk);
 };
 
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispcsiphy.c index 5be37ce..f027ece 100644

drivers/media/video/omap3isp/ispcsiphy.c +0 -0
@@ -28,6 +28,8 @@
 #include <linux/device.h>
 #include <linux/regulator/consumer.h>
 
Quoted 6 lines

drivers/media/video/omap3isp/ispcsiphy.c line 32

Quoted 2 lines
drivers/media/video/omap3isp/ispcsiphy.c +2 -0
+#include "../../../../arch/arm/mach-omap2/control.h"
+

#include <mach/control.h>

(untested) ?

I'm afraid it won't work. The above directory isn't in any include path and likely shouldn't be. That file is included locally elsewhere, I believe.

I wonder what would be the right way to access that register definition I need from the file:

	OMAP343X_CTRL_BASE
	OMAP3630_CONTROL_CAMERA_PHY_CTRL
Quoted 33 lines
Quoted 33 lines
drivers/media/video/omap3isp/ispcsiphy.c +20 -3
 #include "isp.h"
 #include "ispreg.h"
 #include "ispcsiphy.h"
@@ -138,15 +140,78 @@ static void csiphy_dphy_config(struct isp_csiphy
 *phy) isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG1);
 }
 
-static int csiphy_config(struct isp_csiphy *phy,
-			 struct isp_csiphy_dphy_cfg *dphy,
-			 struct isp_csiphy_lanes_cfg *lanes)
+/*
+ * TCLK values are OK at their reset values
+ */
+#define TCLK_TERM	0
+#define TCLK_MISS	1
+#define TCLK_SETTLE	14
+
+int omap3isp_csiphy_config(struct isp_device *isp,
+			   struct v4l2_subdev *csi2_subdev,
+			   struct v4l2_subdev *sensor,
+			   struct v4l2_mbus_framefmt *sensor_fmt)
 {
+	struct isp_v4l2_subdevs_group *subdevs = sensor->host_priv;
+	struct isp_csi2_device *csi2 = v4l2_get_subdevdata(csi2_subdev);
+	struct isp_csiphy_dphy_cfg csi2phy;
+	int csi2_ddrclk_khz;
+	struct isp_csiphy_lanes_cfg *lanes;
 	unsigned int used_lanes = 0;
 	unsigned int i;
+	u32 cam_phy_ctrl;
+
+	if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1
+	    || subdevs->interface == ISP_INTERFACE_CCP2B_PHY2)
Quoted 8 lines

drivers/media/video/omap3isp/ispcsiphy.c static void csiphy_dphy_config(struct isp_csiphy *phy) · line 168

Quoted 3 lines
drivers/media/video/omap3isp/ispcsiphy.c +3 -0
+		lanes = subdevs->bus.ccp2.lanecfg;
+	else
+		lanes = subdevs->bus.csi2.lanecfg;

Shouldn't lane configuration be retrieved from the sensor instead ? Sensors could use different lane configuration depending on the mode. This could also be implemented later when needed, but I don't think it would be too difficult to get it right now.

I think we'd first need to standardise the CSI-2 bus configuration. I don't see a practical need to make the lane configuration dynamic. You could just use a lower frequency to achieve the same if you really need to.

Ideally it might be nice to do but there's really nothing I know that required or even benefited from it --- at least for now.

Quoted 24 lines
Quoted 24 lines
drivers/media/video/omap3isp/ispcsiphy.c +24 -0
+
+	if (!lanes) {
+		dev_err(isp->dev, "no lane configuration\n");
+		return -EINVAL;
+	}
+
+	cam_phy_ctrl = omap_readl(
+		OMAP343X_CTRL_BASE + OMAP3630_CONTROL_CAMERA_PHY_CTRL);
+	/*
+	 * SCM.CONTROL_CAMERA_PHY_CTRL
+	 * - bit[4]    : CSIPHY1 data sent to CSIB
+	 * - bit [3:2] : CSIPHY1 config: 00 d-phy, 01/10 ccp2
+	 * - bit [1:0] : CSIPHY2 config: 00 d-phy, 01/10 ccp2
+	 */
+	if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1)
+		cam_phy_ctrl |= 1 << 2;
+	else if (subdevs->interface == ISP_INTERFACE_CSI2C_PHY1)
+		cam_phy_ctrl &= 1 << 2;
+
+	if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY2)
+		cam_phy_ctrl |= 1;
+	else if (subdevs->interface == ISP_INTERFACE_CSI2A_PHY2)
+		cam_phy_ctrl &= 1;
+
Quoted 8 lines

drivers/media/video/omap3isp/ispcsiphy.c static void csiphy_dphy_config(struct isp_csiphy *phy) · line 197

Quoted 5 lines
drivers/media/video/omap3isp/ispcsiphy.c +5 -0
+	/* FIXME: Do 34xx / 35xx require something here? */
+	if (cpu_is_omap3630())
+		omap_writel(cam_phy_ctrl,
+			    OMAP343X_CTRL_BASE
+			    + OMAP3630_CONTROL_CAMERA_PHY_CTRL);

You use cam_phy_ctrl inside the if statement only, you can move its computation there.

Will fix.

Quoted 61 lines
Quoted 60 lines
drivers/media/video/omap3isp/ispcsiphy.c +19 -7
+
+	csi2_ddrclk_khz = sensor_fmt->pixelrate
+		/ (2 * csi2->phy->num_data_lanes)
+		* omap3isp_video_format_info(sensor_fmt->code)->bpp;
+
+	/*
+	 * THS_TERM: Programmed value = ceil(12.5 ns/DDRClk period) - 1.
+	 * THS_SETTLE: Programmed value = ceil(90 ns/DDRClk period) + 3.
+	 */
+	csi2phy.ths_term = DIV_ROUND_UP(25 * csi2_ddrclk_khz, 2000000) - 1;
+	csi2phy.ths_settle = DIV_ROUND_UP(90 * csi2_ddrclk_khz, 1000000) + 3;
+	csi2phy.tclk_term = TCLK_TERM;
+	csi2phy.tclk_miss = TCLK_MISS;
+	csi2phy.tclk_settle = TCLK_SETTLE;
 
 	/* Clock and data lanes verification */
-	for (i = 0; i < phy->num_data_lanes; i++) {
+	for (i = 0; i < csi2->phy->num_data_lanes; i++) {
 		if (lanes->data[i].pol > 1 || lanes->data[i].pos > 3)
 			return -EINVAL;
 
@@ -162,10 +227,10 @@ static int csiphy_config(struct isp_csiphy *phy,
 	if (lanes->clk.pos == 0 || used_lanes & (1 << lanes->clk.pos))
 		return -EINVAL;
 
-	mutex_lock(&phy->mutex);
-	phy->dphy = *dphy;
-	phy->lanes = *lanes;
-	mutex_unlock(&phy->mutex);
+	mutex_lock(&csi2->phy->mutex);
+	csi2->phy->dphy = csi2phy;
+	csi2->phy->lanes = *lanes;
+	mutex_unlock(&csi2->phy->mutex);
 
 	return 0;
 }
@@ -225,8 +290,6 @@ int omap3isp_csiphy_init(struct isp_device *isp)
 	struct isp_csiphy *phy1 = &isp->isp_csiphy1;
 	struct isp_csiphy *phy2 = &isp->isp_csiphy2;
 
-	isp->platform_cb.csiphy_config = csiphy_config;
-
 	phy2->isp = isp;
 	phy2->csi2 = &isp->isp_csi2a;
 	phy2->num_data_lanes = ISP_CSIPHY2_NUM_DATA_LANES;
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispcsiphy.h index e93a661..9f93222 100644

drivers/media/video/omap3isp/ispcsiphy.h +4 -0
@@ -56,6 +56,10 @@ struct isp_csiphy {
 	struct isp_csiphy_dphy_cfg dphy;
 };
 
+int omap3isp_csiphy_config(struct isp_device *isp,
+			   struct v4l2_subdev *csi2_subdev,
+			   struct v4l2_subdev *sensor,
+			   struct v4l2_mbus_framefmt *fmt);
 int omap3isp_csiphy_acquire(struct isp_csiphy *phy);
 void omap3isp_csiphy_release(struct isp_csiphy *phy);
 int omap3isp_csiphy_init(struct isp_device *isp);
Signature · 2 lines
Sakari Ailus
[email protected]
#54 lore raw

Re: [RFC 13/17] omap3isp: Configure CSI-2 phy based on platform data

Hi Sakari,

Quoted 8 lines · On Saturday 07 January 2012 23:51:24 Sakari Ailus wrote:
Quoted 7 lines · Laurent Pinchart
Quoted 6 lines · On Tuesday 20 December 2011 21:28:05 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Configure CSI-2 phy based on platform data in the ISP driver rather than in platform code.

[snip]

Quoted 14 lines
Quoted 14 lines

drivers/media/video/omap3isp/ispcsiphy.c line 33

Quoted 11 lines
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispcsiphy.c index 5be37ce..f027ece 100644

drivers/media/video/omap3isp/ispcsiphy.c +2 -0
@@ -28,6 +28,8 @@
 
 #include <linux/device.h>
 #include <linux/regulator/consumer.h>
 
+#include "../../../../arch/arm/mach-omap2/control.h"
+

#include <mach/control.h>

Quoted 5 lines
Quoted 1 line

(untested) ?

I'm afraid it won't work. The above directory isn't in any include path and likely shouldn't be. That file is included locally elsewhere, I believe.

You're right, I spoke too fast.

Quoted 5 lines

I wonder what would be the right way to access that register definition I need from the file:

	OMAP343X_CTRL_BASE
	OMAP3630_CONTROL_CAMERA_PHY_CTRL

Maybe the file (or part of it) should be moved to an include directory ?

Quoted 48 lines
Quoted 35 lines
Quoted 35 lines
drivers/media/video/omap3isp/ispcsiphy.c +0 -0
 #include "isp.h"
 #include "ispreg.h"

#include "ispcsiphy.h"

drivers/media/video/omap3isp/ispcsiphy.c +16 -3
@@ -138,15 +140,78 @@ static void csiphy_dphy_config(struct isp_csiphy
 *phy) isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG1);
 
 }
 
-static int csiphy_config(struct isp_csiphy *phy,
-			 struct isp_csiphy_dphy_cfg *dphy,
-			 struct isp_csiphy_lanes_cfg *lanes)
+/*
+ * TCLK values are OK at their reset values
+ */
+#define TCLK_TERM	0
+#define TCLK_MISS	1
+#define TCLK_SETTLE	14
+
+int omap3isp_csiphy_config(struct isp_device *isp,
+			   struct v4l2_subdev *csi2_subdev,
+			   struct v4l2_subdev *sensor,
+			   struct v4l2_mbus_framefmt *sensor_fmt)
 
 {
 
+	struct isp_v4l2_subdevs_group *subdevs = sensor->host_priv;
+	struct isp_csi2_device *csi2 = v4l2_get_subdevdata(csi2_subdev);
+	struct isp_csiphy_dphy_cfg csi2phy;
+	int csi2_ddrclk_khz;
+	struct isp_csiphy_lanes_cfg *lanes;
 
 	unsigned int used_lanes = 0;
 	unsigned int i;
 
Quoted 12 lines

drivers/media/video/omap3isp/ispcsiphy.c static void csiphy_dphy_config(struct isp_csiphy *phy) · line 168

Quoted 7 lines
drivers/media/video/omap3isp/ispcsiphy.c +7 -0
+	u32 cam_phy_ctrl;
+
+	if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1
+	    || subdevs->interface == ISP_INTERFACE_CCP2B_PHY2)
+		lanes = subdevs->bus.ccp2.lanecfg;
+	else
+		lanes = subdevs->bus.csi2.lanecfg;

Shouldn't lane configuration be retrieved from the sensor instead ? Sensors could use different lane configuration depending on the mode. This could also be implemented later when needed, but I don't think it would be too difficult to get it right now.

Quoted 6 lines

I think we'd first need to standardise the CSI-2 bus configuration. I don't see a practical need to make the lane configuration dynamic. You could just use a lower frequency to achieve the same if you really need to.

Ideally it might be nice to do but there's really nothing I know that required or even benefited from it --- at least for now.

Does this mean that lane configuration needs to be duplicated in board code, on for the SMIA++ platform data and one of the OMAP3 ISP platform data ?

Signature · 3 lines
Regards,

Laurent Pinchart
#55 lore raw

Re: [RFC 13/17] omap3isp: Configure CSI-2 phy based on platform data

Hi Laurent,

Quoted 36 lines · Laurent Pinchart

Hi Sakari,

Quoted 8 lines · On Saturday 07 January 2012 23:51:24 Sakari Ailus wrote:
Quoted 7 lines · Laurent Pinchart
Quoted 6 lines · On Tuesday 20 December 2011 21:28:05 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Configure CSI-2 phy based on platform data in the ISP driver rather than in platform code.

[snip]

Quoted 14 lines
Quoted 14 lines

drivers/media/video/omap3isp/ispcsiphy.c line 33

Quoted 11 lines
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispcsiphy.c index 5be37ce..f027ece 100644

drivers/media/video/omap3isp/ispcsiphy.c +2 -0
@@ -28,6 +28,8 @@
 
 #include <linux/device.h>
 #include <linux/regulator/consumer.h>
 
+#include "../../../../arch/arm/mach-omap2/control.h"
+

#include <mach/control.h>

Quoted 5 lines
Quoted 1 line

(untested) ?

I'm afraid it won't work. The above directory isn't in any include path and likely shouldn't be. That file is included locally elsewhere, I believe.

You're right, I spoke too fast.

Quoted 7 lines
Quoted 5 lines

I wonder what would be the right way to access that register definition I need from the file:

	OMAP343X_CTRL_BASE
	OMAP3630_CONTROL_CAMERA_PHY_CTRL

Maybe the file (or part of it) should be moved to an include directory ?

Yes, but which one?

Quoted 52 lines
Quoted 52 lines
Quoted 35 lines
Quoted 35 lines
drivers/media/video/omap3isp/ispcsiphy.c +0 -0
 #include "isp.h"
 #include "ispreg.h"

#include "ispcsiphy.h"

drivers/media/video/omap3isp/ispcsiphy.c +16 -3
@@ -138,15 +140,78 @@ static void csiphy_dphy_config(struct isp_csiphy
 *phy) isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG1);
 
 }
 
-static int csiphy_config(struct isp_csiphy *phy,
-			 struct isp_csiphy_dphy_cfg *dphy,
-			 struct isp_csiphy_lanes_cfg *lanes)
+/*
+ * TCLK values are OK at their reset values
+ */
+#define TCLK_TERM	0
+#define TCLK_MISS	1
+#define TCLK_SETTLE	14
+
+int omap3isp_csiphy_config(struct isp_device *isp,
+			   struct v4l2_subdev *csi2_subdev,
+			   struct v4l2_subdev *sensor,
+			   struct v4l2_mbus_framefmt *sensor_fmt)
 
 {
 
+	struct isp_v4l2_subdevs_group *subdevs = sensor->host_priv;
+	struct isp_csi2_device *csi2 = v4l2_get_subdevdata(csi2_subdev);
+	struct isp_csiphy_dphy_cfg csi2phy;
+	int csi2_ddrclk_khz;
+	struct isp_csiphy_lanes_cfg *lanes;
 
 	unsigned int used_lanes = 0;
 	unsigned int i;
 
Quoted 12 lines

drivers/media/video/omap3isp/ispcsiphy.c static void csiphy_dphy_config(struct isp_csiphy *phy) · line 168

Quoted 7 lines
drivers/media/video/omap3isp/ispcsiphy.c +7 -0
+	u32 cam_phy_ctrl;
+
+	if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1
+	    || subdevs->interface == ISP_INTERFACE_CCP2B_PHY2)
+		lanes = subdevs->bus.ccp2.lanecfg;
+	else
+		lanes = subdevs->bus.csi2.lanecfg;

Shouldn't lane configuration be retrieved from the sensor instead ? Sensors could use different lane configuration depending on the mode. This could also be implemented later when needed, but I don't think it would be too difficult to get it right now.

I think we'd first need to standardise the CSI-2 bus configuration. I don't see a practical need to make the lane configuration dynamic. You could just use a lower frequency to achieve the same if you really need to.

Quoted 5 lines
Quoted 2 lines

Ideally it might be nice to do but there's really nothing I know that required or even benefited from it --- at least for now.

Does this mean that lane configuration needs to be duplicated in board code, on for the SMIA++ platform data and one of the OMAP3 ISP platform data ?

It's mostly the number of lanes, and the polarity --- in theory it is possible to invert the signals on the bus, albeit I'm not sure if anyone does that; I can't see a reason for that, but hey, I don't know why it's possible to specify polarity either. :-)

If both sides support mapping of the lanes, a mapping that matches on both sides has to be provided.

I agree we should standardise the configuration of CSI-2 as well as the configuration of other busses. However, I would prefer to do that later on since I'm already depending on a number of other patches on the SMIA++ driver.

Signature · 2 lines
Sakari Ailus
[email protected]
#56 lore raw

Re: [RFC 13/17] omap3isp: Configure CSI-2 phy based on platform data

Hi,

Quoted 12 lines · Sakari Ailus
Quoted 12 lines
Quoted 11 lines
Quoted 4 lines

Shouldn't lane configuration be retrieved from the sensor instead ? Sensors could use different lane configuration depending on the mode. This could also be implemented later when needed, but I don't think it would be too difficult to get it right now.

I think we'd first need to standardise the CSI-2 bus configuration. I don't see a practical need to make the lane configuration dynamic. You could just use a lower frequency to achieve the same if you really need to.

Ideally it might be nice to do but there's really nothing I know that required or even benefited from it --- at least for now.

Quoted 7 lines
Quoted 2 lines

Does this mean that lane configuration needs to be duplicated in board code, on for the SMIA++ platform data and one of the OMAP3 ISP platform data ?

It's mostly the number of lanes, and the polarity --- in theory it is possible to invert the signals on the bus, albeit I'm not sure if anyone does that; I can't see a reason for that, but hey, I don't know why it's possible to specify polarity either. :-)

I've never seen polarity configuration option in any datasheet, neither MIPI CSI-2 or D-PHY mentions that. Does OMAP3 ISP really allow MIPI-CSI lane signal polarity configuration ? MIPI-CSI2 uses differential signals after all. What would be a point of changing polarity ?

Quoted 2 lines

If both sides support mapping of the lanes, a mapping that matches on both sides has to be provided.

In Samsung SoC (both sensor and host interface) I've seen only possibility to configure the number of data lanes, FWIW I think it is assumed that when you use e.g. 2 data lanes always lane1 and lane2 are utilised for transmission, for 3 lanes - lane 1,2,3, etc. Also I've never seen on schematics that someone wires data lane3 and lane4 when only 2 lanes are utilised, so this makes me wonder if the lane mapping is ever needed.

Has anyone different experience with that ?

Also the standard seem to specify that Data1+ lane at a transmitter(Tx) is connected to Data1+ lane at a receiver(Rx), Data1-(Tx) to Data1-(Rx), Data2+(Tx) to Data2+(Rx), etc. I think this is needed due to explicitly defined data distribution and merging scheme among the lanes, i.e. to allow interworking of various receivers and transmitters.

Thus it seems all we need need is just a number of data lanes used.

Quoted 4 lines

I agree we should standardise the configuration of CSI-2 as well as the configuration of other busses. However, I would prefer to do that later on since I'm already depending on a number of other patches on the SMIA++ driver.

--

Regards,
Sylwester

#57 lore raw

Re: [RFC 13/17] omap3isp: Configure CSI-2 phy based on platform data

Hi Sylwester,

Quoted 23 lines · Sylwester Nawrocki

Hi,

Quoted 12 lines · Sakari Ailus
Quoted 12 lines
Quoted 11 lines
Quoted 4 lines

Shouldn't lane configuration be retrieved from the sensor instead ? Sensors could use different lane configuration depending on the mode. This could also be implemented later when needed, but I don't think it would be too difficult to get it right now.

I think we'd first need to standardise the CSI-2 bus configuration. I don't see a practical need to make the lane configuration dynamic. You could just use a lower frequency to achieve the same if you really need to.

Ideally it might be nice to do but there's really nothing I know that required or even benefited from it --- at least for now.

Quoted 7 lines
Quoted 2 lines

Does this mean that lane configuration needs to be duplicated in board code, on for the SMIA++ platform data and one of the OMAP3 ISP platform data ?

It's mostly the number of lanes, and the polarity --- in theory it is possible to invert the signals on the bus, albeit I'm not sure if anyone does that; I can't see a reason for that, but hey, I don't know why it's possible to specify polarity either. :-)

Quoted 4 lines

I've never seen polarity configuration option in any datasheet, neither MIPI CSI-2 or D-PHY mentions that. Does OMAP3 ISP really allow MIPI-CSI lane signal polarity configuration ? MIPI-CSI2 uses differential signals after all. What would be a point of changing polarity ?

I don't know. It's also the same for CSI-1 on OMAP 3.

This is actually one of the issues here: also device specific configuration is required. The standard configuration must contain probably at least what the spec defines.

Quoted 12 lines
Quoted 2 lines

If both sides support mapping of the lanes, a mapping that matches on both sides has to be provided.

In Samsung SoC (both sensor and host interface) I've seen only possibility to configure the number of data lanes, FWIW I think it is assumed that when you use e.g. 2 data lanes always lane1 and lane2 are utilised for transmission, for 3 lanes - lane 1,2,3, etc. Also I've never seen on schematics that someone wires data lane3 and lane4 when only 2 lanes are utilised, so this makes me wonder if the lane mapping is ever needed.

Has anyone different experience with that ?

Quoted 7 lines

Also the standard seem to specify that Data1+ lane at a transmitter(Tx) is connected to Data1+ lane at a receiver(Rx), Data1-(Tx) to Data1-(Rx), Data2+(Tx) to Data2+(Rx), etc. I think this is needed due to explicitly defined data distribution and merging scheme among the lanes, i.e. to allow interworking of various receivers and transmitters.

Thus it seems all we need need is just a number of data lanes used.

The standard of course specifies that the data lanes must be connected correctly. :-) It can't specify which SoC pins do they use, so for added flexibility it's good to be able to reorder them.

Have you ever worked with single-layer PCBs by any chance? :-) More layers are used these days but it still doesn't solve all possible issues.

So I think I can say reordering generally must be supported by software if the hardware can do that.

Signature · 2 lines
Sakari Ailus
[email protected]
#58 lore raw

Re: [RFC 13/17] omap3isp: Configure CSI-2 phy based on platform data

Hi Sakari,

Quoted 12 lines · Sakari Ailus
Quoted 12 lines
Quoted 12 lines
Quoted 12 lines
Quoted 11 lines
Quoted 4 lines

Shouldn't lane configuration be retrieved from the sensor instead ? Sensors could use different lane configuration depending on the mode. This could also be implemented later when needed, but I don't think it would be too difficult to get it right now.

I think we'd first need to standardise the CSI-2 bus configuration. I don't see a practical need to make the lane configuration dynamic. You could just use a lower frequency to achieve the same if you really need to.

Ideally it might be nice to do but there's really nothing I know that required or even benefited from it --- at least for now.

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 2 lines

Does this mean that lane configuration needs to be duplicated in board code, on for the SMIA++ platform data and one of the OMAP3 ISP platform data ?

It's mostly the number of lanes, and the polarity --- in theory it is possible to invert the signals on the bus, albeit I'm not sure if anyone does that; I can't see a reason for that, but hey, I don't know why it's possible to specify polarity either. :-)

I think it just enables to swap D+ and D- functions on the physical pins.

Quoted 29 lines
Quoted 4 lines

I've never seen polarity configuration option in any datasheet, neither MIPI CSI-2 or D-PHY mentions that. Does OMAP3 ISP really allow MIPI-CSI lane signal polarity configuration ? MIPI-CSI2 uses differential signals after all. What would be a point of changing polarity ?

I don't know. It's also the same for CSI-1 on OMAP 3.

This is actually one of the issues here: also device specific configuration is required. The standard configuration must contain probably at least what the spec defines.

Quoted 18 lines
Quoted 2 lines

If both sides support mapping of the lanes, a mapping that matches on both sides has to be provided.

In Samsung SoC (both sensor and host interface) I've seen only possibility to configure the number of data lanes, FWIW I think it is assumed that when you use e.g. 2 data lanes always lane1 and lane2 are utilised for transmission, for 3 lanes - lane 1,2,3, etc. Also I've never seen on schematics that someone wires data lane3 and lane4 when only 2 lanes are utilised, so this makes me wonder if the lane mapping is ever needed.

Has anyone different experience with that ?

Also the standard seem to specify that Data1+ lane at a transmitter(Tx) is connected to Data1+ lane at a receiver(Rx), Data1-(Tx) to Data1-(Rx), Data2+(Tx) to Data2+(Rx), etc. I think this is needed due to explicitly defined data distribution and merging scheme among the lanes, i.e. to allow interworking of various receivers and transmitters.

Quoted 8 lines
Quoted 1 line

Thus it seems all we need need is just a number of data lanes used.

The standard of course specifies that the data lanes must be connected correctly. :-) It can't specify which SoC pins do they use, so for added flexibility it's good to be able to reorder them.

Have you ever worked with single-layer PCBs by any chance? :-) More layers are used these days but it still doesn't solve all possible issues.

Yes, I have. I know what you mean. It just seemed uncommon to me to reorder the signals. But since H/W doing that exists..and that might become more widely used in the future it might make sense to standardize lane configuration.

Quoted 2 lines

So I think I can say reordering generally must be supported by software if the hardware can do that.

Yes, however there is always a board specific information involved, isn't it ? I.e. transmitter can reorder signals between its pins, the same can happen at a receiver and additionally the transmitter's pins can be connected differently to the receiver pins, depending on the board ?

Then do we make board specific information part of sensor's or host platform data ? It probably should be at both, let's take an evaluation and a camera daughter boards as an example.

We also need device tree bindings for that, if possible the best would be to design common bindings, at least basic ones, to which device specific ones could be added.

--
Regards,
Sylwester

#59 lore raw

Re: [RFC 13/17] omap3isp: Configure CSI-2 phy based on platform data

Hi Sylwester,

Quoted 16 lines · Sylwester Nawrocki
Quoted 15 lines · Sakari Ailus
Quoted 15 lines
Quoted 15 lines
Quoted 14 lines
Quoted 11 lines
Quoted 4 lines

Shouldn't lane configuration be retrieved from the sensor instead ? Sensors could use different lane configuration depending on the mode. This could also be implemented later when needed, but I don't think it would be too difficult to get it right now.

I think we'd first need to standardise the CSI-2 bus configuration. I don't see a practical need to make the lane configuration dynamic. You could just use a lower frequency to achieve the same if you really need to.

Ideally it might be nice to do but there's really nothing I know that required or even benefited from it --- at least for now.

Does this mean that lane configuration needs to be duplicated in board code, on for the SMIA++ platform data and one of the OMAP3 ISP platform data ?

Quoted 6 lines
Quoted 4 lines
Quoted 4 lines
Quoted 4 lines

It's mostly the number of lanes, and the polarity --- in theory it is possible to invert the signals on the bus, albeit I'm not sure if anyone does that; I can't see a reason for that, but hey, I don't know why it's possible to specify polarity either. :-)

I think it just enables to swap D+ and D- functions on the physical pins.

Good thinking. :-) Yeah, it's differential, so yes, I think so too now that you mention it.

Quoted 35 lines
Quoted 35 lines
Quoted 4 lines

I've never seen polarity configuration option in any datasheet, neither MIPI CSI-2 or D-PHY mentions that. Does OMAP3 ISP really allow MIPI-CSI lane signal polarity configuration ? MIPI-CSI2 uses differential signals after all. What would be a point of changing polarity ?

I don't know. It's also the same for CSI-1 on OMAP 3.

This is actually one of the issues here: also device specific configuration is required. The standard configuration must contain probably at least what the spec defines.

Quoted 12 lines
Quoted 2 lines

If both sides support mapping of the lanes, a mapping that matches on both sides has to be provided.

In Samsung SoC (both sensor and host interface) I've seen only possibility to configure the number of data lanes, FWIW I think it is assumed that when you use e.g. 2 data lanes always lane1 and lane2 are utilised for transmission, for 3 lanes - lane 1,2,3, etc. Also I've never seen on schematics that someone wires data lane3 and lane4 when only 2 lanes are utilised, so this makes me wonder if the lane mapping is ever needed.

Has anyone different experience with that ?

Quoted 7 lines

Also the standard seem to specify that Data1+ lane at a transmitter(Tx) is connected to Data1+ lane at a receiver(Rx), Data1-(Tx) to Data1-(Rx), Data2+(Tx) to Data2+(Rx), etc. I think this is needed due to explicitly defined data distribution and merging scheme among the lanes, i.e. to allow interworking of various receivers and transmitters.

Thus it seems all we need need is just a number of data lanes used.

The standard of course specifies that the data lanes must be connected correctly. :-) It can't specify which SoC pins do they use, so for added flexibility it's good to be able to reorder them.

Quoted 7 lines
Quoted 2 lines

Have you ever worked with single-layer PCBs by any chance? :-) More layers are used these days but it still doesn't solve all possible issues.

Yes, I have. I know what you mean. It just seemed uncommon to me to reorder the signals. But since H/W doing that exists..and that might become more widely used in the future it might make sense to standardize lane configuration.

We'll need different mapping configuration for the receiver and the transmitter, and not all the hardware supports it. It won't be many bytes, though.

Quoted 7 lines
Quoted 2 lines

So I think I can say reordering generally must be supported by software if the hardware can do that.

Yes, however there is always a board specific information involved, isn't it ? I.e. transmitter can reorder signals between its pins, the same can happen at a receiver and additionally the transmitter's pins can be connected differently to the receiver pins, depending on the board ?

Exactly. That's the reason, I think, why the hardware does support it.

Quoted 7 lines

Then do we make board specific information part of sensor's or host platform data ? It probably should be at both, let's take an evaluation and a camera daughter boards as an example.

We also need device tree bindings for that, if possible the best would be to design common bindings, at least basic ones, to which device specific ones could be added.

Sounds good to me.

Signature · 2 lines
Sakari Ailus
[email protected]
#60 lore raw

Re: [RFC 13/17] omap3isp: Configure CSI-2 phy based on platform data

In reply to Sakari Ailus

Hi Sakari,

Quoted 37 lines · On Sunday 08 January 2012 11:26:02 Sakari Ailus wrote:
Quoted 36 lines · Laurent Pinchart
Quoted 8 lines · On Saturday 07 January 2012 23:51:24 Sakari Ailus wrote:
Quoted 7 lines · Laurent Pinchart
Quoted 6 lines · On Tuesday 20 December 2011 21:28:05 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Configure CSI-2 phy based on platform data in the ISP driver rather than in platform code.

[snip]

Quoted 14 lines
Quoted 14 lines

drivers/media/video/omap3isp/ispcsiphy.c line 33

Quoted 11 lines
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispcsiphy.c index 5be37ce..f027ece 100644 --- a/drivers/media/video/omap3isp/ispcsiphy.c +++ b/drivers/media/video/omap3isp/ispcsiphy.c

drivers/media/video/omap3isp/ispcsiphy.c +2 -0
@@ -28,6 +28,8 @@
 
 #include <linux/device.h>
 #include <linux/regulator/consumer.h>
 
+#include "../../../../arch/arm/mach-omap2/control.h"
+

#include <mach/control.h>

Quoted 5 lines
Quoted 1 line

(untested) ?

I'm afraid it won't work. The above directory isn't in any include path and likely shouldn't be. That file is included locally elsewhere, I believe.

You're right, I spoke too fast.

Quoted 2 lines

I wonder what would be the right way to access that register definition

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines

I need from the file:

	OMAP343X_CTRL_BASE
	OMAP3630_CONTROL_CAMERA_PHY_CTRL

Maybe the file (or part of it) should be moved to an include directory ?

Yes, but which one?

Good question. The content of control.h doesn't seem to have been meant to be exported. Maybe you should ask on [email protected] ?

Quoted 65 lines
Quoted 53 lines
Quoted 53 lines
Quoted 35 lines
Quoted 35 lines
drivers/media/video/omap3isp/ispcsiphy.c +0 -0
 #include "isp.h"
 #include "ispreg.h"

#include "ispcsiphy.h"

drivers/media/video/omap3isp/ispcsiphy.c +16 -3
@@ -138,15 +140,78 @@ static void csiphy_dphy_config(struct isp_csiphy
 *phy) isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG1);
 
 }
 
-static int csiphy_config(struct isp_csiphy *phy,
-			 struct isp_csiphy_dphy_cfg *dphy,
-			 struct isp_csiphy_lanes_cfg *lanes)
+/*
+ * TCLK values are OK at their reset values
+ */
+#define TCLK_TERM	0
+#define TCLK_MISS	1
+#define TCLK_SETTLE	14
+
+int omap3isp_csiphy_config(struct isp_device *isp,
+			   struct v4l2_subdev *csi2_subdev,
+			   struct v4l2_subdev *sensor,
+			   struct v4l2_mbus_framefmt *sensor_fmt)
 
 {
 
+	struct isp_v4l2_subdevs_group *subdevs = sensor->host_priv;
+	struct isp_csi2_device *csi2 = v4l2_get_subdevdata(csi2_subdev);
+	struct isp_csiphy_dphy_cfg csi2phy;
+	int csi2_ddrclk_khz;
+	struct isp_csiphy_lanes_cfg *lanes;
 
 	unsigned int used_lanes = 0;
 	unsigned int i;
 
Quoted 12 lines

drivers/media/video/omap3isp/ispcsiphy.c static void csiphy_dphy_config(struct isp_csiphy *phy) · line 168

Quoted 7 lines
drivers/media/video/omap3isp/ispcsiphy.c +7 -0
+	u32 cam_phy_ctrl;
+
+	if (subdevs->interface == ISP_INTERFACE_CCP2B_PHY1
+	    || subdevs->interface == ISP_INTERFACE_CCP2B_PHY2)
+		lanes = subdevs->bus.ccp2.lanecfg;
+	else
+		lanes = subdevs->bus.csi2.lanecfg;

Shouldn't lane configuration be retrieved from the sensor instead ? Sensors could use different lane configuration depending on the mode. This could also be implemented later when needed, but I don't think it would be too difficult to get it right now.

I think we'd first need to standardise the CSI-2 bus configuration. I don't see a practical need to make the lane configuration dynamic. You could just use a lower frequency to achieve the same if you really need to.

Quoted 6 lines
Quoted 2 lines

Ideally it might be nice to do but there's really nothing I know that required or even benefited from it --- at least for now.

Does this mean that lane configuration needs to be duplicated in board code, on for the SMIA++ platform data and one of the OMAP3 ISP platform data ?

It's mostly the number of lanes, and the polarity --- in theory it is possible to invert the signals on the bus, albeit I'm not sure if anyone does that; I can't see a reason for that, but hey, I don't know why it's possible to specify polarity either. :-)

Quoted 7 lines

If both sides support mapping of the lanes, a mapping that matches on both sides has to be provided.

I agree we should standardise the configuration of CSI-2 as well as the configuration of other busses. However, I would prefer to do that later on since I'm already depending on a number of other patches on the SMIA++ driver.

OK.

Signature · 3 lines
Regards,

Laurent Pinchart
#61 lore raw

RFC 14/17 omap3isp: Use pixelrate from sensor media bus frameformat

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

Configure the ISP based on the pixelrate in media bus frame format. Previously the same was configured from the board code.

---
 drivers/media/video/omap3isp/isp.c |   24 +++++++++++++++++++++---
 drivers/media/video/omap3isp/isp.h |    1 -
 2 files changed, 21 insertions(+), 4 deletions(-)
drivers/media/video/omap3isp/isp.c +21 -3
index 6020fd7..92f9716 100644
@@ -749,10 +749,14 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
 
 	entity = &pipe->output->video.entity;
 	while (1) {
-		pad = &entity->pads[0];
-		if (!(pad->flags & MEDIA_PAD_FL_SINK))
+		/*
+		 * Is this an external subdev connected to us? If so,
+		 * we're done.
+		 */
+		if (subdev && subdev->host_priv)
 			break;
 
+		pad = &entity->pads[0];
 		pad = media_entity_remote_source(pad);
 		if (pad == NULL ||
 		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
@@ -762,6 +766,21 @@ static int isp_pipeline_enable(struct isp_pipeline *pipe,
 		prev_subdev = subdev;
 		subdev = media_entity_to_v4l2_subdev(entity);
 
+		/* Configure CCDC pixel clock */
+		if (subdev->host_priv) {
+			struct v4l2_subdev_format fmt;
+
+			fmt.pad = pad->index;
+			fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+			ret = v4l2_subdev_call(subdev, pad, get_fmt,
+					       NULL, &fmt);
+			if (ret < 0)
+				return -EINVAL;
+
+			isp_set_pixel_clock(isp,
+					    fmt.format.pixelrate * 1000);
+		}
+
 		/* Configure CSI-2 receiver based on sensor format. */
 		if (prev_subdev == &isp->isp_csi2a.subdev
 		    || prev_subdev == &isp->isp_csi2c.subdev) {
@@ -2102,7 +2121,6 @@ static int isp_probe(struct platform_device *pdev)
 
 	isp->autoidle = autoidle;
 	isp->platform_cb.set_xclk = isp_set_xclk;
-	isp->platform_cb.set_pixel_clock = isp_set_pixel_clock;
 
 	mutex_init(&isp->isp_mutex);
 	spin_lock_init(&isp->stat_lock);
drivers/media/video/omap3isp/isp.h +0 -1
index c5935ae..7d73a39 100644
@@ -126,7 +126,6 @@ struct isp_reg {
 
 struct isp_platform_callback {
 	u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel);
-	void (*set_pixel_clock)(struct isp_device *isp, unsigned int pixelclk);
 };
 
 /*
Signature · 1 line
1.7.2.5
#62 lore raw

Re: [RFC 14/17] omap3isp: Use pixelrate from sensor media bus frameformat

Hi Sakari,

Thanks for the patch.

Quoted 18 lines · On Tuesday 20 December 2011 21:28:06 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Configure the ISP based on the pixelrate in media bus frame format. Previously the same was configured from the board code.

---
 drivers/media/video/omap3isp/isp.c |   24 +++++++++++++++++++++---
 drivers/media/video/omap3isp/isp.h |    1 -
 2 files changed, 21 insertions(+), 4 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/isp.c index 6020fd7..92f9716 100644

drivers/media/video/omap3isp/isp.c +0 -0
@@ -749,10 +749,14 @@ static int isp_pipeline_enable(struct isp_pipeline
 *pipe,
 

drivers/media/video/omap3isp/isp.c static int isp_pipeline_enable(struct isp_pipeline · line 758

Quoted 10 lines
drivers/media/video/omap3isp/isp.c +5 -2
 	entity = &pipe->output->video.entity;
 	while (1) {
-		pad = &entity->pads[0];
-		if (!(pad->flags & MEDIA_PAD_FL_SINK))
+		/*
+		 * Is this an external subdev connected to us? If so,
+		 * we're done.
+		 */
+		if (subdev && subdev->host_priv)
 			break;

This doesn't seem to be related to the patch title. Should it be moved to a separate patch ? You could also move the check to the bottom of the while loop, it would allow you to remove the first part of the condition as subdev will always be non-NULL then (or even possible as the while() condition).

Quoted 48 lines
drivers/media/video/omap3isp/isp.c +16 -0
+		pad = &entity->pads[0];
 		pad = media_entity_remote_source(pad);
 		if (pad == NULL ||
 		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
@@ -762,6 +766,21 @@ static int isp_pipeline_enable(struct isp_pipeline
 *pipe, prev_subdev = subdev;
 		subdev = media_entity_to_v4l2_subdev(entity);
 
+		/* Configure CCDC pixel clock */
+		if (subdev->host_priv) {
+			struct v4l2_subdev_format fmt;
+
+			fmt.pad = pad->index;
+			fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+			ret = v4l2_subdev_call(subdev, pad, get_fmt,
+					       NULL, &fmt);
+			if (ret < 0)
+				return -EINVAL;
+
+			isp_set_pixel_clock(isp,
+					    fmt.format.pixelrate * 1000);
+		}
+
 		/* Configure CSI-2 receiver based on sensor format. */
 		if (prev_subdev == &isp->isp_csi2a.subdev
 
drivers/media/video/omap3isp/isp.c +0 -1
 		    || prev_subdev == &isp->isp_csi2c.subdev) {
@@ -2102,7 +2121,6 @@ static int isp_probe(struct platform_device *pdev)
 
 	isp->autoidle = autoidle;
 	isp->platform_cb.set_xclk = isp_set_xclk;
-	isp->platform_cb.set_pixel_clock = isp_set_pixel_clock;
 
 	mutex_init(&isp->isp_mutex);
 	spin_lock_init(&isp->stat_lock);
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/isp.h index c5935ae..7d73a39 100644

drivers/media/video/omap3isp/isp.h +0 -1
@@ -126,7 +126,6 @@ struct isp_reg {
 
 struct isp_platform_callback {
 	u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel);
-	void (*set_pixel_clock)(struct isp_device *isp, unsigned int pixelclk);
 };
 
 /*
Signature · 3 lines
Regards,

Laurent Pinchart
#63 lore raw

Re: [RFC 14/17] omap3isp: Use pixelrate from sensor media bus frameformat

Hi Laurent,

Quoted 19 lines · Laurent Pinchart
Quoted 18 lines · On Tuesday 20 December 2011 21:28:06 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Configure the ISP based on the pixelrate in media bus frame format. Previously the same was configured from the board code.

---
 drivers/media/video/omap3isp/isp.c |   24 +++++++++++++++++++++---
 drivers/media/video/omap3isp/isp.h |    1 -
 2 files changed, 21 insertions(+), 4 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/isp.c index 6020fd7..92f9716 100644

drivers/media/video/omap3isp/isp.c +0 -0
@@ -749,10 +749,14 @@ static int isp_pipeline_enable(struct isp_pipeline
 *pipe,
 
Quoted 15 lines

drivers/media/video/omap3isp/isp.c static int isp_pipeline_enable(struct isp_pipeline *pipe, · line 757

Quoted 10 lines
drivers/media/video/omap3isp/isp.c +5 -2
 	entity = &pipe->output->video.entity;
 	while (1) {
-		pad = &entity->pads[0];
-		if (!(pad->flags & MEDIA_PAD_FL_SINK))
+		/*
+		 * Is this an external subdev connected to us? If so,
+		 * we're done.
+		 */
+		if (subdev && subdev->host_priv)
 			break;

This doesn't seem to be related to the patch title. Should it be moved to a separate patch ? You could also move the check to the bottom of the while loop, it would allow you to remove the first part of the condition as subdev will always be non-NULL then (or even possible as the while() condition).

The change got removed based on your other suggestions. ;-) The CSI-2 configuration moved to csi2_set_stream, so a lot of cruft got removed from here.

Quoted 49 lines
Quoted 48 lines
drivers/media/video/omap3isp/isp.c +16 -0
+		pad = &entity->pads[0];
 		pad = media_entity_remote_source(pad);
 		if (pad == NULL ||
 		    media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
@@ -762,6 +766,21 @@ static int isp_pipeline_enable(struct isp_pipeline
 *pipe, prev_subdev = subdev;
 		subdev = media_entity_to_v4l2_subdev(entity);
 
+		/* Configure CCDC pixel clock */
+		if (subdev->host_priv) {
+			struct v4l2_subdev_format fmt;
+
+			fmt.pad = pad->index;
+			fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+			ret = v4l2_subdev_call(subdev, pad, get_fmt,
+					       NULL, &fmt);
+			if (ret < 0)
+				return -EINVAL;
+
+			isp_set_pixel_clock(isp,
+					    fmt.format.pixelrate * 1000);
+		}
+
 		/* Configure CSI-2 receiver based on sensor format. */
 		if (prev_subdev == &isp->isp_csi2a.subdev
 
drivers/media/video/omap3isp/isp.c +0 -1
 		    || prev_subdev == &isp->isp_csi2c.subdev) {
@@ -2102,7 +2121,6 @@ static int isp_probe(struct platform_device *pdev)
 
 	isp->autoidle = autoidle;
 	isp->platform_cb.set_xclk = isp_set_xclk;
-	isp->platform_cb.set_pixel_clock = isp_set_pixel_clock;
 
 	mutex_init(&isp->isp_mutex);
 	spin_lock_init(&isp->stat_lock);
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/isp.h index c5935ae..7d73a39 100644

drivers/media/video/omap3isp/isp.h +0 -1
@@ -126,7 +126,6 @@ struct isp_reg {
 
 struct isp_platform_callback {
 	u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel);
-	void (*set_pixel_clock)(struct isp_device *isp, unsigned int pixelclk);
 };
 
 /*
Signature · 2 lines
Sakari Ailus
[email protected]
#64 lore raw

RFC 15/17 omap3isp: Move definitions required by board code under include/media.

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

XCLK definitions are often required by the board code. Move them to public include file.

---
 drivers/media/video/omap3isp/isp.h |    4 ----
 include/media/omap3isp.h           |    4 ++++
 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/media/video/omap3isp/isp.h +0 -4
index 7d73a39..dd1b61e 100644
@@ -235,10 +235,6 @@ void omap3isp_configure_bridge(struct isp_device *isp,
 			       const struct isp_parallel_platform_data *pdata,
 			       unsigned int shift);
 
-#define ISP_XCLK_NONE			0
-#define ISP_XCLK_A			1
-#define ISP_XCLK_B			2
-
 struct isp_device *omap3isp_get(struct isp_device *isp);
 void omap3isp_put(struct isp_device *isp);
 
include/media/omap3isp.h +4 -0
index 8fe0bdf..deb3949 100644
@@ -29,6 +29,10 @@
 struct i2c_board_info;
 struct isp_device;
 
+#define ISP_XCLK_NONE			0
+#define ISP_XCLK_A			1
+#define ISP_XCLK_B			2
+
 enum isp_interface_type {
 	ISP_INTERFACE_PARALLEL,
 	ISP_INTERFACE_CSI2A_PHY2,
Signature · 1 line
1.7.2.5
#65 lore raw

RFC 16/17 smiapp: Add driver.

In reply to Sakari Ailus

Add driver for SMIA++/SMIA image sensors. The driver exposes the sensor as three subdevs, pixel array, binner and scaler --- in case the device has a scaler.

Currently it relies on the board code for external clock handling. There is no fast way out of this dependency before the ISP drivers (omap3isp) among others will be able to export that clock through the clock framework instead.

---
 drivers/media/video/Kconfig           |   13 +
 drivers/media/video/Makefile          |    3 +
 drivers/media/video/smiapp-core.c     | 2595 +++++++++++++++++++++++++++++++++
 drivers/media/video/smiapp-debug.h    |   32 +
 drivers/media/video/smiapp-limits.c   |  132 ++
 drivers/media/video/smiapp-limits.h   |  128 ++
 drivers/media/video/smiapp-pll.c      |  664 +++++++++
 drivers/media/video/smiapp-quirk.c    |  264 ++++
 drivers/media/video/smiapp-quirk.h    |   72 +
 drivers/media/video/smiapp-reg-defs.h |  733 ++++++++++
 drivers/media/video/smiapp-reg.h      |  119 ++
 drivers/media/video/smiapp-regs.c     |  222 +++
 drivers/media/video/smiapp.h          |  250 ++++
 include/media/smiapp-regs.h           |   51 +
 include/media/smiapp.h                |   82 +
 15 files changed, 5360 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/smiapp-core.c
 create mode 100644 drivers/media/video/smiapp-debug.h
 create mode 100644 drivers/media/video/smiapp-limits.c
 create mode 100644 drivers/media/video/smiapp-limits.h
 create mode 100644 drivers/media/video/smiapp-pll.c
 create mode 100644 drivers/media/video/smiapp-quirk.c
 create mode 100644 drivers/media/video/smiapp-quirk.h
 create mode 100644 drivers/media/video/smiapp-reg-defs.h
 create mode 100644 drivers/media/video/smiapp-reg.h
 create mode 100644 drivers/media/video/smiapp-regs.c
 create mode 100644 drivers/media/video/smiapp.h
 create mode 100644 include/media/smiapp-regs.h
 create mode 100644 include/media/smiapp.h
drivers/media/video/Kconfig +13 -0
index 4e8a0c4..0aa8f13 100644
@@ -524,6 +524,19 @@ 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_SMIAPP
+	tristate "SMIA++/SMIA sensor support"
+	depends on I2C && VIDEO_V4L2
+	---help---
+	  This is a generic driver for SMIA++/SMIA camera modules.
+
+config VIDEO_SMIAPP_DEBUG
+	bool "Enable debugging for the generic SMIA++/SMIA driver"
+	depends on VIDEO_SMIAPP
+	---help---
+	  Enable debugging output in the generic SMIA++/SMIA driver. If you
+	  are developing the driver you might want to enable this.
+
 comment "Flash devices"
 
 config VIDEO_ADP1653
drivers/media/video/Makefile +3 -0
index ddeaa6c..82a0cea 100644
@@ -73,6 +73,9 @@ obj-$(CONFIG_VIDEO_SR030PC30)	+= sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)	+= noon010pc30.o
 obj-$(CONFIG_VIDEO_M5MOLS)	+= m5mols/
 obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
+smiapp-objs			+= smiapp-core.o smiapp-regs.o smiapp-pll.o \
+				   smiapp-quirk.o smiapp-limits.o
+obj-$(CONFIG_VIDEO_SMIAPP)	+= smiapp.o
 obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
 
 obj-$(CONFIG_SOC_CAMERA_IMX074)		+= imx074.o
drivers/media/video/smiapp-core.c new file +2595 -0

2,595 lines not on this page · raw message

drivers/media/video/smiapp-debug.h new file +32 -0
new file mode 100644
index 0000000..0cbad12
@@ -0,0 +1,32 @@
+/*
+ * drivers/media/video/smiapp-debug.h
+ *
+ * Generic driver for SMIA/SMIA++ compliant camera modules
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Contact: Sakari Ailus <[email protected]>
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef SMIAPP_DEBUG_H
+#define SMIAPP_DEBUG_H
+
+#ifdef CONFIG_VIDEO_SMIAPP_DEBUG
+#define DEBUG
+#endif
+
+#endif
drivers/media/video/smiapp-limits.c new file +132 -0

132 lines not on this page · raw message

drivers/media/video/smiapp-limits.h new file +128 -0

128 lines not on this page · raw message

drivers/media/video/smiapp-pll.c new file +664 -0

85 lines not on this page · raw message

drivers/media/video/smiapp-quirk.c new file +264 -0

264 lines not on this page · raw message

drivers/media/video/smiapp-quirk.h new file +72 -0

72 lines not on this page · raw message

drivers/media/video/smiapp-reg-defs.h new file +733 -0

733 lines not on this page · raw message

drivers/media/video/smiapp-reg.h new file +119 -0

119 lines not on this page · raw message

drivers/media/video/smiapp-regs.c new file +222 -0

222 lines not on this page · raw message

drivers/media/video/smiapp.h new file +250 -0

250 lines not on this page · raw message

include/media/smiapp-regs.h new file +51 -0

51 lines not on this page · raw message

include/media/smiapp.h new file +82 -0

82 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Signature · 1 line
1.7.2.5

Part of the diff is not shown here. View the raw message.

#66 lore raw

Re: [RFC 16/17] smiapp: Add driver.

Hi Sakari,

I have a just a few comments below. It was rather brief a review, given the size of the patch.. :-)

Quoted 27 lines · Sakari Ailus

Add driver for SMIA++/SMIA image sensors. The driver exposes the sensor as three subdevs, pixel array, binner and scaler --- in case the device has a scaler.

Currently it relies on the board code for external clock handling. There is no fast way out of this dependency before the ISP drivers (omap3isp) among others will be able to export that clock through the clock framework instead.

---
  drivers/media/video/Kconfig           |   13 +
  drivers/media/video/Makefile          |    3 +
  drivers/media/video/smiapp-core.c     | 2595 +++++++++++++++++++++++++++++++++
  drivers/media/video/smiapp-debug.h    |   32 +
  drivers/media/video/smiapp-limits.c   |  132 ++
  drivers/media/video/smiapp-limits.h   |  128 ++
  drivers/media/video/smiapp-pll.c      |  664 +++++++++
  drivers/media/video/smiapp-quirk.c    |  264 ++++
  drivers/media/video/smiapp-quirk.h    |   72 +
  drivers/media/video/smiapp-reg-defs.h |  733 ++++++++++
  drivers/media/video/smiapp-reg.h      |  119 ++
  drivers/media/video/smiapp-regs.c     |  222 +++
  drivers/media/video/smiapp.h          |  250 ++++
  include/media/smiapp-regs.h           |   51 +
  include/media/smiapp.h                |   82 +
  15 files changed, 5360 insertions(+), 0 deletions(-)
Quoted 11 lines

create mode 100644 drivers/media/video/smiapp-core.c create mode 100644 drivers/media/video/smiapp-debug.h create mode 100644 drivers/media/video/smiapp-limits.c create mode 100644 drivers/media/video/smiapp-limits.h create mode 100644 drivers/media/video/smiapp-pll.c create mode 100644 drivers/media/video/smiapp-quirk.c create mode 100644 drivers/media/video/smiapp-quirk.h create mode 100644 drivers/media/video/smiapp-reg-defs.h create mode 100644 drivers/media/video/smiapp-reg.h create mode 100644 drivers/media/video/smiapp-regs.c create mode 100644 drivers/media/video/smiapp.h

How about creating new directory, e.g. drivers/media/video/smiapp/ ?

Quoted 8 lines

create mode 100644 include/media/smiapp-regs.h
create mode 100644 include/media/smiapp.h

drivers/media/video/Kconfig +0 -0
index 4e8a0c4..0aa8f13 100644

drivers/media/video/Kconfig config VIDEO_S5K6AA · line 529

Quoted 6 lines
drivers/media/video/Kconfig +3 -0
@@ -524,6 +524,19 @@ 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_SMIAPP
+	tristate "SMIA++/SMIA sensor support"
+	depends on I2C&&  VIDEO_V4L2

There is no dependency on VIDEO_V4L2_SUBDEV_API ?

Quoted 100 lines
drivers/media/video/Kconfig +10 -0
+	---help---
+	  This is a generic driver for SMIA++/SMIA camera modules.
+
+config VIDEO_SMIAPP_DEBUG
+	bool "Enable debugging for the generic SMIA++/SMIA driver"
+	depends on VIDEO_SMIAPP
+	---help---
+	  Enable debugging output in the generic SMIA++/SMIA driver. If you
+	  are developing the driver you might want to enable this.
+
  comment "Flash devices"
 
  config VIDEO_ADP1653
drivers/media/video/Makefile +3 -0
index ddeaa6c..82a0cea 100644
@@ -73,6 +73,9 @@ obj-$(CONFIG_VIDEO_SR030PC30)	+= sr030pc30.o
  obj-$(CONFIG_VIDEO_NOON010PC30)	+= noon010pc30.o
  obj-$(CONFIG_VIDEO_M5MOLS)	+= m5mols/
  obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
+smiapp-objs			+= smiapp-core.o smiapp-regs.o smiapp-pll.o \
+				   smiapp-quirk.o smiapp-limits.o
+obj-$(CONFIG_VIDEO_SMIAPP)	+= smiapp.o
  obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
 
  obj-$(CONFIG_SOC_CAMERA_IMX074)		+= imx074.o
drivers/media/video/smiapp-core.c new file +67 -0
new file mode 100644
index 0000000..1d15c1d
@@ -0,0 +1,2595 @@
+/*
+ * drivers/media/video/smiapp-core.c
+ *
+ * Generic driver for SMIA/SMIA++ compliant camera modules
+ *
+ * Copyright (C) 2010--2011 Nokia Corporation
+ * Contact: Sakari Ailus<[email protected]>
+ *
+ * Based on smiapp driver by Vimarsh Zutshi
+ * Based on jt8ev1.c by Vimarsh Zutshi
+ * Based on smia-sensor.c by Tuukka Toivonen<[email protected]>
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "smiapp-debug.h"
+
+#include<linux/delay.h>
+#include<linux/device.h>
+#include<linux/module.h>
+#include<linux/regulator/consumer.h>
+#include<linux/v4l2-mediabus.h>
+#include<media/v4l2-device.h>
+
+#include "smiapp.h"
+
+#define SMIAPP_ALIGN_DIM(dim, flags)	      \
+	(flags&  V4L2_SUBDEV_SEL_FLAG_SIZE_GE \
+	 ? ALIGN(dim, 2)		      \
+	 : dim&  ~1)
+
+/*
+ * smiapp_module_idents - supported camera modules
+ */
+static const struct smiapp_module_ident smiapp_module_idents[] = {
+	SMIAPP_IDENT_LQ(0x10, 0x4141, -1, "jt8ev1",&smiapp_jt8ev1_quirk),
+	SMIAPP_IDENT_LQ(0x10, 0x4241, -1, "imx125es",&smiapp_imx125es_quirk),
+	SMIAPP_IDENT_L(0x01, 0x022b, -1, "vs6555"),
+	SMIAPP_IDENT_L(0x0c, 0x208a, -1, "tcm8330md"),
+	SMIAPP_IDENT_L(0x01, 0x022e, -1, "vw6558"),
+	SMIAPP_IDENT_LQ(0x0c, 0x2134, -1, "tcm8500md",&smiapp_tcm8500md_quirk),
+	SMIAPP_IDENT_L(0x07, 0x7698, -1, "ovm7698"),
+	SMIAPP_IDENT_L(0x0b, 0x4242, -1, "smiapp-003"),
+	SMIAPP_IDENT_LQ(0x0c, 0x560f, -1, "jt8ew9",&smiapp_jt8ew9_quirk),
+	SMIAPP_IDENT_L(0x0c, 0x213e, -1, "et8en2"),
+	SMIAPP_IDENT_L(0x0c, 0x2184, -1, "tcm8580md"),
+};
+
+/*
+ *
+ * Dynamic Capability Identification
+ *
+ */
+

[...]

Quoted 13 lines
drivers/media/video/smiapp-core.c new file +13 -0
+/*
+ *
+ * V4L2 Controls handling
+ *
+ */
+
+static void __smiapp_update_exposure_limits(struct smiapp_sensor *sensor)
+{
+	struct v4l2_ctrl *ctrl = sensor->exposure;
+	int max;
+
+	max = sensor->pixel_array->compose[SMIAPP_PAD_SOURCE].height
+		+ sensor->vblank->val -

drivers/media/video/smiapp-core.c line 229

Quoted 10 lines
drivers/media/video/smiapp-core.c new file +10 -0
+		sensor->limits[SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MAX_MARGIN];
+
+	ctrl->maximum = max;
+	if (ctrl->default_value>  max)
+		ctrl->default_value = max;
+	if (ctrl->val>  max)
+		ctrl->val = max;
+	if (ctrl->cur.val>  max)
+		ctrl->cur.val = max;
+}

One more driver that needs control value range update. :)

Quoted 1 line

+

[...]

drivers/media/video/smiapp-core.c line 1457

Quoted 3 lines
drivers/media/video/smiapp-core.c new file +3 -0
+
+#define SCALING_GOODNESS		100000
+#define SCALING_GOODNESS_EXTREME	100000000

Interesting parameter.. :)

Quoted 38 lines
drivers/media/video/smiapp-core.c new file +38 -0
+static int scaling_goodness(struct v4l2_subdev *subdev, int w, int ask_w,
+			    int h, int ask_h, u32 flags)
+{
+	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+	struct i2c_client *client = v4l2_get_subdevdata(subdev);
+	int val = 0;
+
+	w&= ~1;
+	ask_w&= ~1;
+	h&= ~1;
+	ask_h&= ~1;
+
+	if (flags&  V4L2_SUBDEV_SEL_FLAG_SIZE_GE) {
+		if (w<  ask_w)
+			val -= SCALING_GOODNESS;
+		if (h<  ask_h)
+			val -= SCALING_GOODNESS;
+	}
+
+	if (flags&  V4L2_SUBDEV_SEL_FLAG_SIZE_LE) {
+		if (w>  ask_w)
+			val -= SCALING_GOODNESS;
+		if (h>  ask_h)
+			val -= SCALING_GOODNESS;
+	}
+
+	val -= abs(w - ask_w);
+	val -= abs(h - ask_h);
+
+	if (w<  sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE])
+		val -= SCALING_GOODNESS_EXTREME;
+
+	dev_dbg(&client->dev, "w %d ask_w %d h %d ask_h %d goodness %d\n",
+		w, ask_h, h, ask_h, val);
+
+	return val;
+}
+

[...]

Quoted 92 lines
drivers/media/video/smiapp-core.c new file +92 -0
+static int smiapp_set_selection(struct v4l2_subdev *subdev,
+				struct v4l2_subdev_fh *fh,
+				struct v4l2_subdev_selection *sel)
+{
+	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+	struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
+	struct v4l2_rect *comps, *crops;
+	int ret;
+
+	ret = __smiapp_sel_supported(subdev, sel);
+	if (ret)
+		return ret;
+
+	sel->r.left = sel->r.left&  ~1;
+	sel->r.top = sel->r.top&  ~1;
+	sel->r.width = SMIAPP_ALIGN_DIM(sel->r.width, sel->flags);
+	sel->r.height = SMIAPP_ALIGN_DIM(sel->r.height, sel->flags);
+
+	if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		crops = ssd->crop;
+		comps = ssd->compose;
+	} else {
+		crops = fh->try_crop;
+		comps = fh->try_compose;
+	}
+
+	sel->r.left&= ~1;
+	sel->r.top&= ~1;
+	sel->r.width&= ~1;
+	sel->r.height&= ~1;
+
+	sel->r.left = max(0, sel->r.left);
+	sel->r.top = max(0, sel->r.top);
+	sel->r.width = max(0, sel->r.width);
+	sel->r.height = max(0, sel->r.height);
+
+	sel->r.width = max_t(unsigned int,
+			     sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
+			     sel->r.width);
+	sel->r.height = max_t(unsigned int,
+			      sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],
+			      sel->r.height);
+
+	switch (sel->target) {
+	case V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE:
+		return smiapp_set_crop(subdev, fh, sel);
+	case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTIVE:
+		return smiapp_set_compose(subdev, fh, sel);
+	}
+
+	BUG();
+}
+
+static int smiapp_validate_pipeline(struct v4l2_subdev *subdev)
+{
+	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+	struct smiapp_subdev *ssds[] = {
+		sensor->scaler, sensor->binner, sensor->pixel_array };
+	int i;
+	struct smiapp_subdev *last = NULL;
+
+	if (sensor->src->crop[SMIAPP_PAD_SOURCE].width
+	<  sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE])
+		return -EPIPE;
+	if (sensor->src->crop[SMIAPP_PAD_SOURCE].height
+	<  sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE])
+		return -EPIPE;
+
+	for (i = 0; i<  SMIAPP_SUBDEVS; i++) {
+		struct smiapp_subdev *this = ssds[i];
+
+		if (!this)
+			continue;
+
+		if (!last) {
+			last = this;
+			continue;
+		}
+
+		if (last->sink_fmt.width
+		    != this->compose[SMIAPP_PAD_SOURCE].width)
+			return -EPIPE;
+		if (last->sink_fmt.height
+		    != this->compose[SMIAPP_PAD_SOURCE].height)
+			return -EPIPE;
+
+		last = this;
+	}
+
+	return 0;
+}
+

[...]

drivers/media/video/smiapp-core.c line 2580

Quoted 8 lines
drivers/media/video/smiapp-core.c new file +8 -0
+
+static int __init smiapp_init(void)
+{
+	int rval;
+
+	rval = i2c_add_driver(&smiapp_i2c_driver);
+	if (rval)
+		printk(KERN_ERR "Failed registering driver" SMIAPP_NAME "\n");

Using pr_<level> is expected for new drivers.

Quoted 15 lines
drivers/media/video/smiapp-core.c new file +15 -0
+
+	return rval;
+}
+
+static void __exit smiapp_exit(void)
+{
+	i2c_del_driver(&smiapp_i2c_driver);
+}
+
+module_init(smiapp_init);
+module_exit(smiapp_exit);
+
+MODULE_AUTHOR("Sakari Ailus<[email protected]>");
+MODULE_DESCRIPTION("Generic SMIA/SMIA++ camera module driver");
+MODULE_LICENSE("GPL");

[...]

Quoted 22 lines
drivers/media/video/smiapp-core.c new file +22 -0
+/*
+ * Write to a 8/16-bit register.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+int smia_i2c_write_reg(struct i2c_client *client, u32 reg, u32 val)
+{
+	struct i2c_msg msg[1];
+	unsigned char data[6];
+	unsigned int retries = 5;
+	unsigned int flags = reg>>  24;
+	unsigned int len = (u8)(reg>>  16);
+	u16 offset = reg;
+	int r;
+
+	if (!client->adapter)
+		return -ENODEV;
+
+	if ((len != SMIA_REG_8BIT&&  len != SMIA_REG_16BIT&&
+	     len != SMIA_REG_32BIT) || flags)
+		return -EINVAL;
+
+	smia_i2c_create_msg(client, len, offset, val, msg, data);

drivers/media/video/smiapp-core.c

Quoted 10 lines
drivers/media/video/smiapp-core.c new file +10 -0
+
+	do {
+		/*
+		 * Due to unknown reason sensor stops responding. This
+		 * loop is a temporaty solution until the root cause
+		 * is found.
+		 */
+		r = i2c_transfer(client->adapter, msg, 1);
+		if (r>= 0)
+			break;

I think r == 0 indicates failure (0 messages transferred), it's probably never returned in that case though. It might be better to test for r == 1.

Quoted 16 lines
drivers/media/video/smiapp-core.c new file +16 -0
+
+		usleep_range(2000, 2000);
+	} while (retries--);
+
+	if (r<  0)
+		dev_err(&client->dev,
+			"wrote 0x%x to offset 0x%x error %d\n", val, offset, r);
+	else
+		r = 0; /* on success i2c_transfer() return messages trasfered */
+
+	if (retries<  5)
+		dev_err(&client->dev, "sensor i2c stall encountered. "
+			"retries: %d\n", 5 - retries);
+
+	return r;
+}

[...]

Quoted 28 lines
include/media/smiapp-regs.h new file +22 -0
new file mode 100644
index 0000000..3109b02
@@ -0,0 +1,51 @@
+/*
+ * include/media/smiapp-regs.h
+ *
+ * Generic driver for SMIA/SMIA++ compliant camera modules
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Contact: Sakari Ailus<[email protected]>
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *

include/media/smiapp-regs.h

Quoted 10 lines
include/media/smiapp-regs.h new file +9 -0
+ */
+
+#ifndef SMIAPP_REGS_H
+#define SMIAPP_REGS_H
+
+#include<linux/i2c.h>
+#include<linux/types.h>
 
+#include<linux/videodev2.h>
+#include<linux/v4l2-subdev.h>

Are these two headers really needed ?

include/media/smiapp-regs.h line 34

Quoted 3 lines
include/media/smiapp-regs.h new file +3 -0
+
+struct v4l2_mbus_framefmt;
+struct v4l2_subdev_pad_mbus_code_enum;

Also these 2 lines seem redundant.

Quoted 92 lines
include/media/smiapp-regs.h new file +17 -0
+
+/* Use upper 8 bits of the type field for flags */
+#define SMIA_REG_FLAG_FLOAT		(1<<  24)
+
+#define SMIA_REG_8BIT			1
+#define SMIA_REG_16BIT			2
+#define SMIA_REG_32BIT			4
+struct smia_reg {
+	u16 type;
+	u16 reg;			/* 16-bit offset */
+	u32 val;			/* 8/16/32-bit value */
+};
+
+int smia_i2c_read_reg(struct i2c_client *client, u32 reg, u32 *val);
+int smia_i2c_write_reg(struct i2c_client *client, u32 reg, u32 val);
+
+#endif
include/media/smiapp.h new file +69 -0
new file mode 100644
index 0000000..b302570
@@ -0,0 +1,82 @@
+/*
+ * include/media/smiapp.h
+ *
+ * Generic driver for SMIA/SMIA++ compliant camera modules
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Contact: Sakari Ailus<[email protected]>
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __SMIAPP_H_
+#define __SMIAPP_H_
+
+#include<media/smiapp-regs.h>
+#include<media/v4l2-subdev.h>
+
+#define SMIAPP_NAME		"smiapp"
+
+#define SMIAPP_DFL_I2C_ADDR	(0x20>>  1) /* Default I2C Address */
+#define SMIAPP_ALT_I2C_ADDR	(0x6e>>  1) /* Alternate I2C Address */
+
+#define SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK	0
+#define SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_STROBE	1
+#define SMIAPP_CSI_SIGNALLING_MODE_CSI2			2
+
+/*
+ * Sometimes due to board layout considerations the camera module can be
+ * mounted rotated. The typical rotation used is 180 degrees which can be
+ * corrected by giving a default H-FLIP and V-FLIP in the sensor readout.
+ * FIXME: rotation also changes the bayer pattern.
+ */
+enum smiapp_module_board_orient {
+	SMIAPP_MODULE_BOARD_ORIENT_0 = 0,
+	SMIAPP_MODULE_BOARD_ORIENT_180,
+};
+
+struct smiapp_flash_strobe_parms {
+	u8 mode;
+	u32 strobe_width_high_us;
+	u16 strobe_delay;
+	u16 stobe_start_point;
+	u8 trigger;
+};
+
+struct smiapp_platform_data {
+	/*
+	 * Change the cci address if i2c_addr_alt is set.
+	 * Both default and alternate cci addr need to be present
+	 */
+	unsigned short i2c_addr_dfl;	/* Default i2c addr */
+	unsigned short i2c_addr_alt;	/* Alternate i2c addr */
+
+	unsigned int nvm_size;			/* bytes */
+	unsigned int ext_clk;			/* sensor external clk */
+

include/media/smiapp.h line 79

Quoted 10 lines
include/media/smiapp.h new file +10 -0
+	unsigned int lanes;		/* Number of CSI-2 lanes */
+	u8 csi_signalling_mode;		/* SMIAPP_CSI_SIGNALLING_MODE_* */
+	const s64 *op_sys_clock;
+
+	enum smiapp_module_board_orient module_board_orient;
+
+	struct smiapp_flash_strobe_parms *strobe_setup;
+
+	int (*set_xclk)(struct v4l2_subdev *sd, int hz);
+	int (*set_xshutdown)(struct v4l2_subdev *sd, u8 set);

There is no chance to avoid this callback, e.g. by passing GPIO(s) number(s) directly to the driver ?

include/media/smiapp.h line 82

Quoted 3 lines
include/media/smiapp.h new file +3 -0
+};
+
+#endif /* __SMIAPP_H_  */

--
Regards,
Sylwester

#67 lore raw

Re: [RFC 16/17] smiapp: Add driver.

Hi Sylwester,

Thanks for the review!!!

Quoted 4 lines · Sylwester Nawrocki

Hi Sakari,

I have a just a few comments below. It was rather brief a review, given the size of the patch.. :-)

Good points. I'll make the changes, as well as those Laurent pointed out, and send a new version of the driver. I expect I'll be able to do that early next week.

Quoted 40 lines · Sakari Ailus
Quoted 27 lines

Add driver for SMIA++/SMIA image sensors. The driver exposes the sensor as three subdevs, pixel array, binner and scaler --- in case the device has a scaler.

Currently it relies on the board code for external clock handling. There is no fast way out of this dependency before the ISP drivers (omap3isp) among others will be able to export that clock through the clock framework instead.

---
  drivers/media/video/Kconfig           |   13 +
  drivers/media/video/Makefile          |    3 +
  drivers/media/video/smiapp-core.c     | 2595 +++++++++++++++++++++++++++++++++
  drivers/media/video/smiapp-debug.h    |   32 +
  drivers/media/video/smiapp-limits.c   |  132 ++
  drivers/media/video/smiapp-limits.h   |  128 ++
  drivers/media/video/smiapp-pll.c      |  664 +++++++++
  drivers/media/video/smiapp-quirk.c    |  264 ++++
  drivers/media/video/smiapp-quirk.h    |   72 +
  drivers/media/video/smiapp-reg-defs.h |  733 ++++++++++
  drivers/media/video/smiapp-reg.h      |  119 ++
  drivers/media/video/smiapp-regs.c     |  222 +++
  drivers/media/video/smiapp.h          |  250 ++++
  include/media/smiapp-regs.h           |   51 +
  include/media/smiapp.h                |   82 +
  15 files changed, 5360 insertions(+), 0 deletions(-)
Quoted 11 lines

create mode 100644 drivers/media/video/smiapp-core.c create mode 100644 drivers/media/video/smiapp-debug.h create mode 100644 drivers/media/video/smiapp-limits.c create mode 100644 drivers/media/video/smiapp-limits.h create mode 100644 drivers/media/video/smiapp-pll.c create mode 100644 drivers/media/video/smiapp-quirk.c create mode 100644 drivers/media/video/smiapp-quirk.h create mode 100644 drivers/media/video/smiapp-reg-defs.h create mode 100644 drivers/media/video/smiapp-reg.h create mode 100644 drivers/media/video/smiapp-regs.c create mode 100644 drivers/media/video/smiapp.h

Quoted 1 line

How about creating new directory, e.g. drivers/media/video/smiapp/ ?

Good question. When I started working on this, I just had a few files which didn't justify creating a new directory. I think you're right; now it's time for that.

Quoted 11 lines
Quoted 11 lines

create mode 100644 include/media/smiapp-regs.h
create mode 100644 include/media/smiapp.h

drivers/media/video/Kconfig +0 -0
index 4e8a0c4..0aa8f13 100644
@@ -524,6 +524,19 @@ 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.
 
Quoted 5 lines

drivers/media/video/Kconfig config VIDEO_S5K6AA

Quoted 3 lines
drivers/media/video/Kconfig +3 -0
+config VIDEO_SMIAPP
+	tristate "SMIA++/SMIA sensor support"
+	depends on I2C&&  VIDEO_V4L2

There is no dependency on VIDEO_V4L2_SUBDEV_API ?

Yes, there is.

Quoted 118 lines
Quoted 100 lines
drivers/media/video/Kconfig +10 -0
+	---help---
+	  This is a generic driver for SMIA++/SMIA camera modules.
+
+config VIDEO_SMIAPP_DEBUG
+	bool "Enable debugging for the generic SMIA++/SMIA driver"
+	depends on VIDEO_SMIAPP
+	---help---
+	  Enable debugging output in the generic SMIA++/SMIA driver. If you
+	  are developing the driver you might want to enable this.
+
  comment "Flash devices"
 
  config VIDEO_ADP1653
drivers/media/video/Makefile +3 -0
index ddeaa6c..82a0cea 100644
@@ -73,6 +73,9 @@ obj-$(CONFIG_VIDEO_SR030PC30)	+= sr030pc30.o
  obj-$(CONFIG_VIDEO_NOON010PC30)	+= noon010pc30.o
  obj-$(CONFIG_VIDEO_M5MOLS)	+= m5mols/
  obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
+smiapp-objs			+= smiapp-core.o smiapp-regs.o smiapp-pll.o \
+				   smiapp-quirk.o smiapp-limits.o
+obj-$(CONFIG_VIDEO_SMIAPP)	+= smiapp.o
  obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
 
  obj-$(CONFIG_SOC_CAMERA_IMX074)		+= imx074.o
drivers/media/video/smiapp-core.c new file +67 -0
new file mode 100644
index 0000000..1d15c1d
@@ -0,0 +1,2595 @@
+/*
+ * drivers/media/video/smiapp-core.c
+ *
+ * Generic driver for SMIA/SMIA++ compliant camera modules
+ *
+ * Copyright (C) 2010--2011 Nokia Corporation
+ * Contact: Sakari Ailus<[email protected]>
+ *
+ * Based on smiapp driver by Vimarsh Zutshi
+ * Based on jt8ev1.c by Vimarsh Zutshi
+ * Based on smia-sensor.c by Tuukka Toivonen<[email protected]>
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "smiapp-debug.h"
+
+#include<linux/delay.h>
+#include<linux/device.h>
+#include<linux/module.h>
+#include<linux/regulator/consumer.h>
+#include<linux/v4l2-mediabus.h>
+#include<media/v4l2-device.h>
+
+#include "smiapp.h"
+
+#define SMIAPP_ALIGN_DIM(dim, flags)	      \
+	(flags&  V4L2_SUBDEV_SEL_FLAG_SIZE_GE \
+	 ? ALIGN(dim, 2)		      \
+	 : dim&  ~1)
+
+/*
+ * smiapp_module_idents - supported camera modules
+ */
+static const struct smiapp_module_ident smiapp_module_idents[] = {
+	SMIAPP_IDENT_LQ(0x10, 0x4141, -1, "jt8ev1",&smiapp_jt8ev1_quirk),
+	SMIAPP_IDENT_LQ(0x10, 0x4241, -1, "imx125es",&smiapp_imx125es_quirk),
+	SMIAPP_IDENT_L(0x01, 0x022b, -1, "vs6555"),
+	SMIAPP_IDENT_L(0x0c, 0x208a, -1, "tcm8330md"),
+	SMIAPP_IDENT_L(0x01, 0x022e, -1, "vw6558"),
+	SMIAPP_IDENT_LQ(0x0c, 0x2134, -1, "tcm8500md",&smiapp_tcm8500md_quirk),
+	SMIAPP_IDENT_L(0x07, 0x7698, -1, "ovm7698"),
+	SMIAPP_IDENT_L(0x0b, 0x4242, -1, "smiapp-003"),
+	SMIAPP_IDENT_LQ(0x0c, 0x560f, -1, "jt8ew9",&smiapp_jt8ew9_quirk),
+	SMIAPP_IDENT_L(0x0c, 0x213e, -1, "et8en2"),
+	SMIAPP_IDENT_L(0x0c, 0x2184, -1, "tcm8580md"),
+};
+
+/*
+ *
+ * Dynamic Capability Identification
+ *
+ */
+

[...]

Quoted 17 lines
drivers/media/video/smiapp-core.c new file +17 -0
+/*
+ *
+ * V4L2 Controls handling
+ *
+ */
+
+static void __smiapp_update_exposure_limits(struct smiapp_sensor *sensor)
+{
+	struct v4l2_ctrl *ctrl = sensor->exposure;
+	int max;
+
+	max = sensor->pixel_array->compose[SMIAPP_PAD_SOURCE].height
+		+ sensor->vblank->val -
+		sensor->limits[SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MAX_MARGIN];
+
+	ctrl->maximum = max;
+	if (ctrl->default_value>  max)
Quoted 8 lines

drivers/media/video/smiapp-core.c line 229

Quoted 6 lines
drivers/media/video/smiapp-core.c new file +6 -0
+		ctrl->default_value = max;
+	if (ctrl->val>  max)
+		ctrl->val = max;
+	if (ctrl->cur.val>  max)
+		ctrl->cur.val = max;
+}

One more driver that needs control value range update. :)

:-)

Are there other drivers that would need something like that, too? Anything in the control framework that I have missed related to this?

Quoted 140 lines
Quoted 1 line

+

[...]

drivers/media/video/smiapp-core.c line 1457

Quoted 3 lines
drivers/media/video/smiapp-core.c new file +3 -0
+
+#define SCALING_GOODNESS		100000
+#define SCALING_GOODNESS_EXTREME	100000000

Interesting parameter.. :)

Quoted 38 lines
drivers/media/video/smiapp-core.c new file +38 -0
+static int scaling_goodness(struct v4l2_subdev *subdev, int w, int ask_w,
+			    int h, int ask_h, u32 flags)
+{
+	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+	struct i2c_client *client = v4l2_get_subdevdata(subdev);
+	int val = 0;
+
+	w&= ~1;
+	ask_w&= ~1;
+	h&= ~1;
+	ask_h&= ~1;
+
+	if (flags&  V4L2_SUBDEV_SEL_FLAG_SIZE_GE) {
+		if (w<  ask_w)
+			val -= SCALING_GOODNESS;
+		if (h<  ask_h)
+			val -= SCALING_GOODNESS;
+	}
+
+	if (flags&  V4L2_SUBDEV_SEL_FLAG_SIZE_LE) {
+		if (w>  ask_w)
+			val -= SCALING_GOODNESS;
+		if (h>  ask_h)
+			val -= SCALING_GOODNESS;
+	}
+
+	val -= abs(w - ask_w);
+	val -= abs(h - ask_h);
+
+	if (w<  sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE])
+		val -= SCALING_GOODNESS_EXTREME;
+
+	dev_dbg(&client->dev, "w %d ask_w %d h %d ask_h %d goodness %d\n",
+		w, ask_h, h, ask_h, val);
+
+	return val;
+}
+

[...]

Quoted 92 lines
drivers/media/video/smiapp-core.c new file +92 -0
+static int smiapp_set_selection(struct v4l2_subdev *subdev,
+				struct v4l2_subdev_fh *fh,
+				struct v4l2_subdev_selection *sel)
+{
+	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+	struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
+	struct v4l2_rect *comps, *crops;
+	int ret;
+
+	ret = __smiapp_sel_supported(subdev, sel);
+	if (ret)
+		return ret;
+
+	sel->r.left = sel->r.left&  ~1;
+	sel->r.top = sel->r.top&  ~1;
+	sel->r.width = SMIAPP_ALIGN_DIM(sel->r.width, sel->flags);
+	sel->r.height = SMIAPP_ALIGN_DIM(sel->r.height, sel->flags);
+
+	if (sel->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		crops = ssd->crop;
+		comps = ssd->compose;
+	} else {
+		crops = fh->try_crop;
+		comps = fh->try_compose;
+	}
+
+	sel->r.left&= ~1;
+	sel->r.top&= ~1;
+	sel->r.width&= ~1;
+	sel->r.height&= ~1;
+
+	sel->r.left = max(0, sel->r.left);
+	sel->r.top = max(0, sel->r.top);
+	sel->r.width = max(0, sel->r.width);
+	sel->r.height = max(0, sel->r.height);
+
+	sel->r.width = max_t(unsigned int,
+			     sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
+			     sel->r.width);
+	sel->r.height = max_t(unsigned int,
+			      sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],
+			      sel->r.height);
+
+	switch (sel->target) {
+	case V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE:
+		return smiapp_set_crop(subdev, fh, sel);
+	case V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTIVE:
+		return smiapp_set_compose(subdev, fh, sel);
+	}
+
+	BUG();
+}
+
+static int smiapp_validate_pipeline(struct v4l2_subdev *subdev)
+{
+	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+	struct smiapp_subdev *ssds[] = {
+		sensor->scaler, sensor->binner, sensor->pixel_array };
+	int i;
+	struct smiapp_subdev *last = NULL;
+
+	if (sensor->src->crop[SMIAPP_PAD_SOURCE].width
+	<  sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE])
+		return -EPIPE;
+	if (sensor->src->crop[SMIAPP_PAD_SOURCE].height
+	<  sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE])
+		return -EPIPE;
+
+	for (i = 0; i<  SMIAPP_SUBDEVS; i++) {
+		struct smiapp_subdev *this = ssds[i];
+
+		if (!this)
+			continue;
+
+		if (!last) {
+			last = this;
+			continue;
+		}
+
+		if (last->sink_fmt.width
+		    != this->compose[SMIAPP_PAD_SOURCE].width)
+			return -EPIPE;
+		if (last->sink_fmt.height
+		    != this->compose[SMIAPP_PAD_SOURCE].height)
+			return -EPIPE;
+
+		last = this;
+	}
+
+	return 0;
+}
+

[...]

Quoted 10 lines

drivers/media/video/smiapp-core.c line 2580

Quoted 8 lines
drivers/media/video/smiapp-core.c new file +8 -0
+
+static int __init smiapp_init(void)
+{
+	int rval;
+
+	rval = i2c_add_driver(&smiapp_i2c_driver);
+	if (rval)
+		printk(KERN_ERR "Failed registering driver" SMIAPP_NAME "\n");

Using pr_<level> is expected for new drivers.

Fixed.

Quoted 44 lines
Quoted 15 lines
drivers/media/video/smiapp-core.c new file +15 -0
+
+	return rval;
+}
+
+static void __exit smiapp_exit(void)
+{
+	i2c_del_driver(&smiapp_i2c_driver);
+}
+
+module_init(smiapp_init);
+module_exit(smiapp_exit);
+
+MODULE_AUTHOR("Sakari Ailus<[email protected]>");
+MODULE_DESCRIPTION("Generic SMIA/SMIA++ camera module driver");
+MODULE_LICENSE("GPL");

[...]

Quoted 27 lines
drivers/media/video/smiapp-core.c new file +27 -0
+/*
+ * Write to a 8/16-bit register.
+ * Returns zero if successful, or non-zero otherwise.
+ */
+int smia_i2c_write_reg(struct i2c_client *client, u32 reg, u32 val)
+{
+	struct i2c_msg msg[1];
+	unsigned char data[6];
+	unsigned int retries = 5;
+	unsigned int flags = reg>>  24;
+	unsigned int len = (u8)(reg>>  16);
+	u16 offset = reg;
+	int r;
+
+	if (!client->adapter)
+		return -ENODEV;
+
+	if ((len != SMIA_REG_8BIT&&  len != SMIA_REG_16BIT&&
+	     len != SMIA_REG_32BIT) || flags)
+		return -EINVAL;
+
+	smia_i2c_create_msg(client, len, offset, val, msg, data);
+
+	do {
+		/*
+		 * Due to unknown reason sensor stops responding. This
+		 * loop is a temporaty solution until the root cause
Quoted 8 lines

drivers/media/video/smiapp-core.c

Quoted 5 lines
drivers/media/video/smiapp-core.c new file +5 -0
+		 * is found.
+		 */
+		r = i2c_transfer(client->adapter, msg, 1);
+		if (r>= 0)
+			break;

I think r == 0 indicates failure (0 messages transferred), it's probably never returned in that case though. It might be better to test for r == 1.

Fixed. By doing so one must make sure that when an error is encountered, a negative error code will be returned.

Quoted 58 lines
Quoted 16 lines
drivers/media/video/smiapp-core.c new file +16 -0
+
+		usleep_range(2000, 2000);
+	} while (retries--);
+
+	if (r<  0)
+		dev_err(&client->dev,
+			"wrote 0x%x to offset 0x%x error %d\n", val, offset, r);
+	else
+		r = 0; /* on success i2c_transfer() return messages trasfered */
+
+	if (retries<  5)
+		dev_err(&client->dev, "sensor i2c stall encountered. "
+			"retries: %d\n", 5 - retries);
+
+	return r;
+}

[...]

Quoted 28 lines
include/media/smiapp-regs.h new file +22 -0
new file mode 100644
index 0000000..3109b02
@@ -0,0 +1,51 @@
+/*
+ * include/media/smiapp-regs.h
+ *
+ * Generic driver for SMIA/SMIA++ compliant camera modules
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Contact: Sakari Ailus<[email protected]>
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *

include/media/smiapp-regs.h

Quoted 10 lines
include/media/smiapp-regs.h new file +9 -0
+ */
+
+#ifndef SMIAPP_REGS_H
+#define SMIAPP_REGS_H
+
+#include<linux/i2c.h>
+#include<linux/types.h>
 
+#include<linux/videodev2.h>
+#include<linux/v4l2-subdev.h>

Are these two headers really needed ?

Quoted 5 lines

include/media/smiapp-regs.h line 34

Quoted 3 lines
include/media/smiapp-regs.h new file +3 -0
+
+struct v4l2_mbus_framefmt;
+struct v4l2_subdev_pad_mbus_code_enum;

Also these 2 lines seem redundant.

Removed both. I think they're remnants from the time this header file used to contain something else as well.

Quoted 97 lines
Quoted 97 lines
include/media/smiapp-regs.h new file +17 -0
+
+/* Use upper 8 bits of the type field for flags */
+#define SMIA_REG_FLAG_FLOAT		(1<<  24)
+
+#define SMIA_REG_8BIT			1
+#define SMIA_REG_16BIT			2
+#define SMIA_REG_32BIT			4
+struct smia_reg {
+	u16 type;
+	u16 reg;			/* 16-bit offset */
+	u32 val;			/* 8/16/32-bit value */
+};
+
+int smia_i2c_read_reg(struct i2c_client *client, u32 reg, u32 *val);
+int smia_i2c_write_reg(struct i2c_client *client, u32 reg, u32 val);
+
+#endif
include/media/smiapp.h new file +74 -0
new file mode 100644
index 0000000..b302570
@@ -0,0 +1,82 @@
+/*
+ * include/media/smiapp.h
+ *
+ * Generic driver for SMIA/SMIA++ compliant camera modules
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Contact: Sakari Ailus<[email protected]>
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#ifndef __SMIAPP_H_
+#define __SMIAPP_H_
+
+#include<media/smiapp-regs.h>
+#include<media/v4l2-subdev.h>
+
+#define SMIAPP_NAME		"smiapp"
+
+#define SMIAPP_DFL_I2C_ADDR	(0x20>>  1) /* Default I2C Address */
+#define SMIAPP_ALT_I2C_ADDR	(0x6e>>  1) /* Alternate I2C Address */
+
+#define SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK	0
+#define SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_STROBE	1
+#define SMIAPP_CSI_SIGNALLING_MODE_CSI2			2
+
+/*
+ * Sometimes due to board layout considerations the camera module can be
+ * mounted rotated. The typical rotation used is 180 degrees which can be
+ * corrected by giving a default H-FLIP and V-FLIP in the sensor readout.
+ * FIXME: rotation also changes the bayer pattern.
+ */
+enum smiapp_module_board_orient {
+	SMIAPP_MODULE_BOARD_ORIENT_0 = 0,
+	SMIAPP_MODULE_BOARD_ORIENT_180,
+};
+
+struct smiapp_flash_strobe_parms {
+	u8 mode;
+	u32 strobe_width_high_us;
+	u16 strobe_delay;
+	u16 stobe_start_point;
+	u8 trigger;
+};
+
+struct smiapp_platform_data {
+	/*
+	 * Change the cci address if i2c_addr_alt is set.
+	 * Both default and alternate cci addr need to be present
+	 */
+	unsigned short i2c_addr_dfl;	/* Default i2c addr */
+	unsigned short i2c_addr_alt;	/* Alternate i2c addr */
+
+	unsigned int nvm_size;			/* bytes */
+	unsigned int ext_clk;			/* sensor external clk */
+
+	unsigned int lanes;		/* Number of CSI-2 lanes */
+	u8 csi_signalling_mode;		/* SMIAPP_CSI_SIGNALLING_MODE_* */
+	const s64 *op_sys_clock;
+
+	enum smiapp_module_board_orient module_board_orient;
Quoted 8 lines

include/media/smiapp.h line 79

Quoted 5 lines
include/media/smiapp.h new file +5 -0
+
+	struct smiapp_flash_strobe_parms *strobe_setup;
+
+	int (*set_xclk)(struct v4l2_subdev *sd, int hz);
+	int (*set_xshutdown)(struct v4l2_subdev *sd, u8 set);

There is no chance to avoid this callback, e.g. by passing GPIO(s) number(s) directly to the driver ?

I think Laurent also commented that. Yes, I'll fix that. We won't get completely rid of these callbacks until we can have the generic clock framework so we could control the ISP external clock to the sensor using the regular clk_* functions.

Quoted 3 lines

include/media/smiapp.h line 82

Quoted 3 lines
include/media/smiapp.h new file +3 -0
+};
+
+#endif /* __SMIAPP_H_  */

Cheers,

Signature · 2 lines
Sakari Ailus
[email protected]
#68 lore raw

Re: [RFC 16/17] smiapp: Add driver.

Hi Sakari,

Quoted 26 lines · Sakari Ailus
Quoted 17 lines
Quoted 17 lines
drivers/media/video/smiapp-core.c new file +17 -0
+/*
+ *
+ * V4L2 Controls handling
+ *
+ */
+
+static void __smiapp_update_exposure_limits(struct smiapp_sensor *sensor)
+{
+	struct v4l2_ctrl *ctrl = sensor->exposure;
+	int max;
+
+	max = sensor->pixel_array->compose[SMIAPP_PAD_SOURCE].height
+		+ sensor->vblank->val -
+		sensor->limits[SMIAPP_LIMIT_COARSE_INTEGRATION_TIME_MAX_MARGIN];
+
+	ctrl->maximum = max;
+	if (ctrl->default_value>   max)
Quoted 8 lines

drivers/media/video/smiapp-core.c line 229

Quoted 6 lines
drivers/media/video/smiapp-core.c new file +6 -0
+		ctrl->default_value = max;
+	if (ctrl->val>   max)
+		ctrl->val = max;
+	if (ctrl->cur.val>   max)
+		ctrl->cur.val = max;
+}

One more driver that needs control value range update. :)

Quoted 4 lines

:-)

Are there other drivers that would need something like that, too? Anything in the control framework that I have missed related to this?

Yes, I needed that in s5p-fimc driver for the alpha component control. The alpha channel value range depends on colour format and the control needs to be updated accordingly to changes done with VIDIOC_S_FMT.

And no, there is yet nothing in the control framework to support this. Hans just prepared some proof-of-concept patch [1], but the decision was to hold on until there appear more drivers needing control value range update, due to hight complication of life in the userland.

[1] http://www.mail-archive.com/[email protected]/msg39674.html

--
Regards,
Sylwester

#69 lore raw

RFC 17/17 rm680: Add camera init

In reply to Sakari Ailus

This currently introduces an extra file to the arch/arm/mach-omap2
directory: board-rm680-camera.c. Keeping the device tree in mind, the context of the file could be represented as static data with one exception:
the external clock to the sensor.

This external clock is provided by the OMAP 3 SoC and required by the sensor. The issue is that the clock originates from the ISP and not from PRCM block as the other clocks and thus is not supported by the clock framework. Otherwise the sensor driver could just clk_get() and clk_enable() it, just like the regulators and gpios.

---
 arch/arm/mach-omap2/Makefile             |    3 +-
 arch/arm/mach-omap2/board-rm680-camera.c |  408 ++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/board-rm680.c        |   42 +++
 3 files changed, 452 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap2/board-rm680-camera.c
arch/arm/mach-omap2/Makefile +2 -1
index 69ab1c0..1444bc5 100644
@@ -201,7 +201,8 @@ obj-$(CONFIG_MACH_OMAP3_PANDORA)	+= board-omap3pandora.o
 obj-$(CONFIG_MACH_OMAP_3430SDP)		+= board-3430sdp.o
 obj-$(CONFIG_MACH_NOKIA_N8X0)		+= board-n8x0.o
 obj-$(CONFIG_MACH_NOKIA_RM680)		+= board-rm680.o \
-					   sdram-nokia.o
+					   sdram-nokia.o \
+					   board-rm680-camera.o
 obj-$(CONFIG_MACH_NOKIA_RX51)		+= board-rx51.o \
 					   sdram-nokia.o \
 					   board-rx51-peripherals.o \
arch/arm/mach-omap2/board-rm680-camera.c new file +408 -0

408 lines not on this page · raw message

arch/arm/mach-omap2/board-rm680.c +42 -0

66 lines not on this page · raw message

Signature · 1 line
1.7.2.5
#70 lore raw

Re: [RFC 17/17] rm680: Add camera init

Hi Sakari,

Thanks for the patch.

Quoted 10 lines · On Tuesday 20 December 2011 21:28:09 Sakari Ailus wrote:

This currently introduces an extra file to the arch/arm/mach-omap2
directory: board-rm680-camera.c. Keeping the device tree in mind, the context of the file could be represented as static data with one exception:
the external clock to the sensor.

This external clock is provided by the OMAP 3 SoC and required by the sensor. The issue is that the clock originates from the ISP and not from PRCM block as the other clocks and thus is not supported by the clock framework. Otherwise the sensor driver could just clk_get() and clk_enable() it, just like the regulators and gpios.

This will hopefully be fixable with the new generic clock struct. Have you had a look at it lately BTW ?

Quoted 29 lines
---
 arch/arm/mach-omap2/Makefile             |    3 +-
 arch/arm/mach-omap2/board-rm680-camera.c |  408
++++++++++++++++++++++++++++++ arch/arm/mach-omap2/board-rm680.c        | 
 42 +++
 3 files changed, 452 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap2/board-rm680-camera.c
arch/arm/mach-omap2/Makefile +0 -0
index 69ab1c0..1444bc5 100644
@@ -201,7 +201,8 @@ obj-$(CONFIG_MACH_OMAP3_PANDORA)	+=

board-omap3pandora.o obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o
obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o
obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o \

arch/arm/mach-omap2/Makefile +2 -1
-					   sdram-nokia.o
+					   sdram-nokia.o \
+					   board-rm680-camera.o
 obj-$(CONFIG_MACH_NOKIA_RX51)		+= board-rx51.o \
 					   sdram-nokia.o \
 					   board-rx51-peripherals.o \
(quoted diff) +0 -0

b/arch/arm/mach-omap2/board-rm680-camera.c new file mode 100644 index 0000000..4cc1ced

arch/arm/mach-omap2/board-rm680-camera.c line 4

Quoted 4 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +4 -0
@@ -0,0 +1,408 @@
+/**
+ * arch/arm/mach-omap2/board-rm680-camera.c
+ *
+ * Copyright (C) 2010--2011 Nokia Corporation

2012 ? :-)

arch/arm/mach-omap2/board-rm680-camera.c line 7

Quoted 3 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +3 -0
+ * Contact: Sakari Ailus <[email protected]>
+ *
+ * Based on board-rx71-camera.c by Vimarsh Zutshi

This one isn't upstream, I'm not sure if it's worth mentioning it.

Quoted 17 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +17 -0
+ * Based on board-rx51-camera.c by Sakari Ailus
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */

arch/arm/mach-omap2/board-rm680-camera.c line 34

Quoted 10 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +10 -0
+
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/videodev2.h>
+
+#include <linux/gpio.h>
+#include <plat/omap-pm.h>
+
+#include "../../../drivers/media/video/omap3isp/isp.h"

What do we still miss in <media/omap3isp.h> ?

arch/arm/mach-omap2/board-rm680-camera.c line 40

Quoted 5 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +5 -0
+#include <media/omap3isp.h>
+#include <media/smiapp.h>
+#include <asm/mach-types.h>
+
+#include "../../../drivers/media/video/smiapp.h"

Time to create <media/smiapp.h> ?

Quoted 18 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +18 -0
+
+#include "devices.h"
+
+#define SEC_CAMERA_RESET_GPIO	97
+
+#define RM680_PRI_SENSOR	1
+#define RM680_PRI_LENS		2
+#define RM680_SEC_SENSOR	3
+#define MAIN_CAMERA_XCLK	ISP_XCLK_A
+#define SEC_CAMERA_XCLK		ISP_XCLK_B
+
+/*
+ *
+ * HW initialization
+ *
+ *
+ */
+static int __init rm680_sec_camera_init(void)

arch/arm/mach-omap2/board-rm680-camera.c line 68

Quoted 10 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +10 -0
+{
+	if (gpio_request(SEC_CAMERA_RESET_GPIO, "sec_camera reset") != 0) {
+		printk(KERN_INFO "%s: unable to acquire secondary "
+		       "camera reset gpio\n", __func__);
+		return -ENODEV;
+	}
+
+	/* XSHUTDOWN off, reset  */
+	gpio_direction_output(SEC_CAMERA_RESET_GPIO, 0);
+	gpio_set_value(SEC_CAMERA_RESET_GPIO, 0);

gpio_request_one() would be helpful here (and possibly in other locations in this file).

arch/arm/mach-omap2/board-rm680-camera.c line 75

Quoted 7 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +7 -0
+
+	return 0;
+}
+
+static int __init rm680_camera_hw_init(void)
+{
+	return rm680_sec_camera_init();

Maybe you could merge the two functions ?

Quoted 172 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +17 -0
+}
+
+/*
+ *
+ * Main Camera Module EXTCLK
+ * Used by the sensor and the actuator driver.
+ *
+ */
+static struct camera_xclk {
+	u32 hz;
+	u32 lock;
+	u8 xclksel;
+} cameras_xclk;
+
+static DEFINE_MUTEX(lock_xclk);
+
+static int rm680_update_xclk(struct v4l2_subdev *subdev, u32 hz, u32

which, + u8 xclksel)

arch/arm/mach-omap2/board-rm680-camera.c new file +142 -0
+{
+	struct isp_device *isp = v4l2_dev_to_isp_device(subdev->v4l2_dev);
+	int ret;
+
+	mutex_lock(&lock_xclk);
+
+	if (which == RM680_SEC_SENSOR) {
+		if (cameras_xclk.xclksel == MAIN_CAMERA_XCLK) {
+			ret = -EBUSY;
+			goto done;
+		}
+	} else {
+		if (cameras_xclk.xclksel == SEC_CAMERA_XCLK) {
+			ret = -EBUSY;
+			goto done;
+		}
+	}
+
+	if (hz) {	/* Turn on */
+		cameras_xclk.lock |= which;
+		if (cameras_xclk.hz == 0) {
+			isp->platform_cb.set_xclk(isp, hz, xclksel);
+			cameras_xclk.hz = hz;
+			cameras_xclk.xclksel = xclksel;
+		}
+	} else {	/* Turn off */
+		cameras_xclk.lock &= ~which;
+		if (cameras_xclk.lock == 0) {
+			isp->platform_cb.set_xclk(isp, 0, xclksel);
+			cameras_xclk.hz = 0;
+			cameras_xclk.xclksel = 0;
+		}
+	}
+
+	ret = cameras_xclk.hz;
+
+done:
+	mutex_unlock(&lock_xclk);
+	return ret;
+}
+
+/*
+ *
+ * Main Camera Sensor
+ *
+ */
+
+static struct isp_csiphy_lanes_cfg rm696_main_camera_csi2_lanecfg = {
+	.clk = {
+		.pol = 1,
+		.pos = 2,
+	},
+	.data[0] = {
+		.pol = 1,
+		.pos = 1,
+	},
+	.data[1] = {
+		.pol = 1,
+		.pos = 3,
+	},
+};
+
+static struct isp_csiphy_lanes_cfg rm680_main_camera_csi2_lanecfg = {
+	.clk = {
+		.pol = 1,
+		.pos = 2,
+	},
+	.data[0] = {
+		.pol = 1,
+		.pos = 3,
+	},
+	.data[1] = {
+		.pol = 1,
+		.pos = 1,
+	},
+};
+
+static int rm680_main_camera_set_xclk(struct v4l2_subdev *sd, int hz)
+{
+	return rm680_update_xclk(sd, hz, RM680_PRI_SENSOR, MAIN_CAMERA_XCLK);
+}
+
+static struct smiapp_flash_strobe_parms rm680_main_camera_strobe_setup = {
+	.mode			= 0x0c,
+	.strobe_width_high_us	= 100000,
+	.strobe_delay		= 0,
+	.stobe_start_point	= 0,
+	.trigger		= 0,
+};
+
+static struct smiapp_platform_data rm696_main_camera_platform_data = {
+	.i2c_addr_dfl		= SMIAPP_DFL_I2C_ADDR,
+	.i2c_addr_alt		= SMIAPP_ALT_I2C_ADDR,
+	.nvm_size		= 16 * 64,
+	.ext_clk		= (9.6 * 1000 * 1000),
+	.lanes			= 2,
+	.op_sys_clock		= (s64 []){ 796800 / 2, 840000 / 2,
+					    1996800 / 2, 0 },
+	.csi_signalling_mode	= SMIAPP_CSI_SIGNALLING_MODE_CSI2,
+	.strobe_setup		= &rm680_main_camera_strobe_setup,
+	.set_xclk		= rm680_main_camera_set_xclk,
+};
+
+static struct smiapp_platform_data rm680_main_camera_platform_data = {
+	.i2c_addr_dfl		= SMIAPP_DFL_I2C_ADDR,
+	.i2c_addr_alt		= SMIAPP_ALT_I2C_ADDR,
+	.nvm_size		= 16 * 64,
+	.ext_clk		= (9.6 * 1000 * 1000),
+	.lanes			= 2,
+	.op_sys_clock		= (s64 []){ 840000 / 2, 1334400 / 2,
+					    1593600 / 2, 0 },
+	.csi_signalling_mode	= SMIAPP_CSI_SIGNALLING_MODE_CSI2,
+	.module_board_orient	= SMIAPP_MODULE_BOARD_ORIENT_180,
+	.strobe_setup		= &rm680_main_camera_strobe_setup,
+	.set_xclk		= rm680_main_camera_set_xclk,
+};
+
+/*
+ *
+ * SECONDARY CAMERA Sensor
+ *
+ */
+
+#define SEC_CAMERA_XCLK		ISP_XCLK_B
+
+static struct isp_csiphy_lanes_cfg rm680_sec_camera_csiphy_lanecfg = {
+	.clk = {
+		.pol = 0,
+		.pos = 1,
+	},
+	.data[0] = {
+		.pol = 0,
+		.pos = 2,
+	},
+};
+
+static int rm680_sec_camera_set_xclk(struct v4l2_subdev *sd, int hz)
+{
+	return rm680_update_xclk(sd, hz, RM680_SEC_SENSOR, SEC_CAMERA_XCLK);
+}
+
+static int rm680_sec_camera_set_xshutdown(struct v4l2_subdev *subdev, u8

set) +{

arch/arm/mach-omap2/board-rm680-camera.c new file +11 -0
+	gpio_set_value(SEC_CAMERA_RESET_GPIO, !!set);
+	return 0;
+}
+
+static struct smiapp_platform_data rm696_sec_camera_platform_data = {
+	.ext_clk		= (10.8 * 1000 * 1000),
+	.lanes			= 1,
+	.op_sys_clock		= (s64 []){ 13770 * 10, 0 },
+	.csi_signalling_mode	= SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK,
+	.module_board_orient	= SMIAPP_MODULE_BOARD_ORIENT_180,
+	.set_xclk		= rm680_sec_camera_set_xclk,

arch/arm/mach-omap2/board-rm680-camera.c line 257

Quoted 10 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +10 -0
+	.set_xshutdown		= rm680_sec_camera_set_xshutdown,
+};
+
+static struct smiapp_platform_data rm680_sec_camera_platform_data = {
+	.ext_clk		= (10.8 * 1000 * 1000),
+	.lanes			= 1,
+	.op_sys_clock		= (s64 []){ 11880 * 10, 0 },
+	.csi_signalling_mode	= SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK,
+	.set_xclk		= rm680_sec_camera_set_xclk,
+	.set_xshutdown		= rm680_sec_camera_set_xshutdown,

What about passing the GPIO number to the smiapp driver instead of using a callback function ?

Quoted 179 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +43 -0
+};
+
+/*
+ *
+ * Init all the modules
+ *
+ */
+
+#define CAMERA_I2C_BUS_NUM		2
+#define AD5836_I2C_BUS_NUM		2
+#define AS3645A_I2C_BUS_NUM		2
+
+static struct i2c_board_info rm696_camera_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO(SMIAPP_NAME, SMIAPP_ALT_I2C_ADDR),
+		.platform_data = &rm696_main_camera_platform_data,
+	},
+	{
+		I2C_BOARD_INFO(SMIAPP_NAME, SMIAPP_DFL_I2C_ADDR),
+		.platform_data = &rm696_sec_camera_platform_data,
+	},
+};
+
+static struct i2c_board_info rm680_camera_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO(SMIAPP_NAME, SMIAPP_ALT_I2C_ADDR),
+		.platform_data = &rm680_main_camera_platform_data,
+	},
+	{
+		I2C_BOARD_INFO(SMIAPP_NAME, SMIAPP_DFL_I2C_ADDR),
+		.platform_data = &rm680_sec_camera_platform_data,
+	},
+};
+
+static struct isp_subdev_i2c_board_info rm696_camera_primary_subdevs[] = {
+	{
+		.board_info = &rm696_camera_i2c_devices[0],
+		.i2c_adapter_id = CAMERA_I2C_BUS_NUM,
+	},
+	{ NULL, 0, },
+};
+
+static struct isp_subdev_i2c_board_info rm696_camera_secondary_subdevs[] =

{ + {

arch/arm/mach-omap2/board-rm680-camera.c new file +15 -0
+		.board_info = &rm696_camera_i2c_devices[1],
+		.i2c_adapter_id = CAMERA_I2C_BUS_NUM,
+	},
+	{ NULL, 0, },
+};
+
+static struct isp_subdev_i2c_board_info rm680_camera_primary_subdevs[] = {
+	{
+		.board_info = &rm680_camera_i2c_devices[0],
+		.i2c_adapter_id = CAMERA_I2C_BUS_NUM,
+	},
+	{ NULL, 0, },
+};
+
+static struct isp_subdev_i2c_board_info rm680_camera_secondary_subdevs[] =

{ + {

arch/arm/mach-omap2/board-rm680-camera.c new file +91 -0
+		.board_info = &rm680_camera_i2c_devices[1],
+		.i2c_adapter_id = CAMERA_I2C_BUS_NUM,
+	},
+	{ NULL, 0, },
+};
+
+static struct isp_v4l2_subdevs_group rm696_camera_subdevs[] = {
+	{
+		.subdevs = rm696_camera_primary_subdevs,
+		.interface = ISP_INTERFACE_CSI2A_PHY2,
+		.bus = { .csi2 = {
+			.crc		= 1,
+			.vpclk_div	= 1,
+			.lanecfg	= &rm696_main_camera_csi2_lanecfg,
+		} },
+	},
+	{
+		.subdevs = rm696_camera_secondary_subdevs,
+		.interface = ISP_INTERFACE_CCP2B_PHY1,
+		.bus = { .ccp2 = {
+			.strobe_clk_pol	= 0,
+			.crc		= 0,
+			.ccp2_mode	= 0,
+			.phy_layer	= 0,
+			.vpclk_div	= 2,
+			.lanecfg	= &rm680_sec_camera_csiphy_lanecfg,
+		} },
+	},
+	{ NULL, 0, },
+};
+
+static struct isp_v4l2_subdevs_group rm680_camera_subdevs[] = {
+	{
+		.subdevs = rm680_camera_primary_subdevs,
+		.interface = ISP_INTERFACE_CSI2A_PHY2,
+		.bus = { .csi2 = {
+			.crc		= 1,
+			.vpclk_div	= 1,
+			.lanecfg	= &rm680_main_camera_csi2_lanecfg,
+		} },
+	},
+	{
+		.subdevs = rm680_camera_secondary_subdevs,
+		.interface = ISP_INTERFACE_CCP2B_PHY1,
+		.bus = { .ccp2 = {
+			.strobe_clk_pol	= 0,
+			.crc		= 0,
+			.ccp2_mode	= 0,
+			.phy_layer	= 0,
+			.vpclk_div	= 2,
+			.lanecfg	= &rm680_sec_camera_csiphy_lanecfg,
+		} },
+	},
+	{ NULL, 0, },
+};
+
+static struct isp_platform_data rm696_isp_platform_data = {
+	.subdevs = rm696_camera_subdevs,
+};
+
+static struct isp_platform_data rm680_isp_platform_data = {
+	.subdevs = rm680_camera_subdevs,
+};
+
+static inline int board_is_rm680(void)
+{
+	return (system_rev & 0x00f0) == 0x0020;
+}
+
+void __init rm680_camera_init(void)
+{
+	struct isp_platform_data *pdata;
+	int rval;
+
+	rval = rm680_camera_hw_init();
+	if (rval) {
+		printk(KERN_WARNING "%s: unable to initialise camera\n",
+		       __func__);
+		return;
+	}
+
+	if (board_is_rm680())
+		pdata = &rm680_isp_platform_data;
+	else
+		pdata = &rm696_isp_platform_data;
+
+	if (omap3_init_camera(pdata) < 0)
+		printk(KERN_WARNING
+		       "%s: unable to register camera platform device\n",
+		       __func__);
+}
(quoted diff) +0 -0

b/arch/arm/mach-omap2/board-rm680.c index a5bcc75..a1e33d4 100644

arch/arm/mach-omap2/board-rm680.c +20 -0
@@ -66,6 +66,43 @@ static struct platform_device rm680_vemmc_device = {
 	},
 };
 
+#define REGULATOR_INIT_DATA(_name, _min, _max, _apply, _ops_mask) \
+	static struct regulator_init_data _name##_data = { \
+		.constraints = { \
+			.name                   = #_name, \
+			.min_uV                 = _min, \
+			.max_uV                 = _max, \
+			.apply_uV               = _apply, \
+			.valid_modes_mask       = REGULATOR_MODE_NORMAL | \
+						REGULATOR_MODE_STANDBY, \
+			.valid_ops_mask         = _ops_mask, \
+		}, \
+		.num_consumer_supplies  = ARRAY_SIZE(_name##_consumers), \
+		.consumer_supplies      = _name##_consumers, \
+}
+#define REGULATOR_INIT_DATA_FIXED(_name, _voltage) \
+	REGULATOR_INIT_DATA(_name, _voltage, _voltage, true, \
+				REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE)
+
+static struct regulator_consumer_supply rm680_vaux2_consumers[] = {
+	REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"),	/* OMAP ISP */

arch/arm/mach-omap2/board-rm680.c static struct platform_device rm680_vemmc_device = { · line 98

Quoted 10 lines
arch/arm/mach-omap2/board-rm680.c +10 -0
+	REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"),	/* OMAP ISP */
+	{
+		.supply		= "vaux2",
+	},
+};
+REGULATOR_INIT_DATA_FIXED(rm680_vaux2, 1800000);
+
+static struct regulator_consumer_supply rm680_vaux3_consumers[] = {
+	REGULATOR_SUPPLY("VANA", "2-0037"),	/* Main Camera Sensor */
+	REGULATOR_SUPPLY("VANA", "2-000e"),	/* Main Camera Lens */

The lens driver isn't upstream yet. We could keep the regulator supply definition to avoid forgetting it later though.

Quoted 36 lines
arch/arm/mach-omap2/board-rm680.c +12 -0
+	REGULATOR_SUPPLY("VANA", "2-0010"),	/* Front Camera */
+	{
+		.supply		= "vaux3",
+	},
+};
+REGULATOR_INIT_DATA_FIXED(rm680_vaux3, 2800000);
+
 static struct platform_device *rm680_peripherals_devices[] __initdata = {
 	&rm680_vemmc_device,
 };
@@ -82,6 +119,8 @@ static struct twl4030_gpio_platform_data rm680_gpio_data
 = { static struct twl4030_platform_data rm680_twl_data = {
 	.gpio			= &rm680_gpio_data,
 	/* add rest of the children here */
+	.vaux2			= &rm680_vaux2_data,
+	.vaux3			= &rm680_vaux3_data,
 };
 
 static void __init rm680_i2c_init(void)
@@ -129,6 +168,8 @@ static struct omap_board_mux board_mux[] __initdata = {
 };
 #endif
 
+void rm680_camera_init(void);
+
 static void __init rm680_init(void)
 {
 	struct omap_sdrc_params *sdrc_params;
@@ -141,6 +182,7 @@ static void __init rm680_init(void)
 
 	usb_musb_init(NULL);
 	rm680_peripherals_init();
+	rm680_camera_init();
 }
 
 MACHINE_START(NOKIA_RM680, "Nokia RM-680 board")
Signature · 3 lines
Regards,

Laurent Pinchart
#71 lore raw

Re: [RFC 17/17] rm680: Add camera init

Hi Laurent,

Thanks for the review!

Quoted 6 lines · Laurent Pinchart
Quoted 5 lines · On Tuesday 20 December 2011 21:28:09 Sakari Ailus wrote:

This currently introduces an extra file to the arch/arm/mach-omap2
directory: board-rm680-camera.c. Keeping the device tree in mind, the context of the file could be represented as static data with one exception:
the external clock to the sensor.

Quoted 8 lines
Quoted 5 lines

This external clock is provided by the OMAP 3 SoC and required by the sensor. The issue is that the clock originates from the ISP and not from PRCM block as the other clocks and thus is not supported by the clock framework. Otherwise the sensor driver could just clk_get() and clk_enable() it, just like the regulators and gpios.

This will hopefully be fixable with the new generic clock struct. Have you had a look at it lately BTW ?

Not since the ELc-E. It'd be nice to get that so we can get rid of the final issue between OMAP 3 ISP and the device tree --- well, there may be others but I can't say to know about them. :-)

Quoted 27 lines
Quoted 27 lines
---
 arch/arm/mach-omap2/Makefile             |    3 +-
 arch/arm/mach-omap2/board-rm680-camera.c |  408
++++++++++++++++++++++++++++++ arch/arm/mach-omap2/board-rm680.c        | 
 42 +++
 3 files changed, 452 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap2/board-rm680-camera.c
arch/arm/mach-omap2/Makefile +0 -0
index 69ab1c0..1444bc5 100644
@@ -201,7 +201,8 @@ obj-$(CONFIG_MACH_OMAP3_PANDORA)	+=

board-omap3pandora.o obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o
obj-$(CONFIG_MACH_NOKIA_N8X0) += board-n8x0.o
obj-$(CONFIG_MACH_NOKIA_RM680) += board-rm680.o \

arch/arm/mach-omap2/Makefile +2 -1
-					   sdram-nokia.o
+					   sdram-nokia.o \
+					   board-rm680-camera.o
 obj-$(CONFIG_MACH_NOKIA_RX51)		+= board-rx51.o \
 					   sdram-nokia.o \
 					   board-rx51-peripherals.o \
(quoted diff) +0 -0

b/arch/arm/mach-omap2/board-rm680-camera.c new file mode 100644 index 0000000..4cc1ced
--- /dev/null

Quoted 8 lines

arch/arm/mach-omap2/board-rm680-camera.c line 4

Quoted 6 lines

+++ b/arch/arm/mach-omap2/board-rm680-camera.c

arch/arm/mach-omap2/board-rm680-camera.c new file +4 -0
@@ -0,0 +1,408 @@
+/**
+ * arch/arm/mach-omap2/board-rm680-camera.c
+ *
+ * Copyright (C) 2010--2011 Nokia Corporation

2012 ? :-)

Good point. I'll make the change for the rest of the files as well.

Quoted 5 lines

arch/arm/mach-omap2/board-rm680-camera.c line 7

Quoted 3 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +3 -0
+ * Contact: Sakari Ailus <[email protected]>
+ *
+ * Based on board-rx71-camera.c by Vimarsh Zutshi

This one isn't upstream, I'm not sure if it's worth mentioning it.

It's still of historical importance; that is still publicly available if not in mainline. If you really think I should remove it I will.

Quoted 21 lines
Quoted 21 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +21 -0
+ * Based on board-rx51-camera.c by Sakari Ailus
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
Quoted 8 lines

arch/arm/mach-omap2/board-rm680-camera.c line 34

Quoted 6 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +6 -0
+#include <linux/videodev2.h>
+
+#include <linux/gpio.h>
+#include <plat/omap-pm.h>
+
+#include "../../../drivers/media/video/omap3isp/isp.h"

What do we still miss in <media/omap3isp.h> ?

I think it's mostly the xclk stuff. Everything else is where it should be.

Quoted 7 lines

arch/arm/mach-omap2/board-rm680-camera.c line 40

Quoted 5 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +5 -0
+#include <media/omap3isp.h>
+#include <media/smiapp.h>
+#include <asm/mach-types.h>
+
+#include "../../../drivers/media/video/smiapp.h"

Time to create <media/smiapp.h> ?

Now that you ask; the file is there and it contains all the necessary definitions. I had forgotten to remove the line. ;-)

Quoted 23 lines
Quoted 23 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +23 -0
+
+#include "devices.h"
+
+#define SEC_CAMERA_RESET_GPIO	97
+
+#define RM680_PRI_SENSOR	1
+#define RM680_PRI_LENS		2
+#define RM680_SEC_SENSOR	3
+#define MAIN_CAMERA_XCLK	ISP_XCLK_A
+#define SEC_CAMERA_XCLK		ISP_XCLK_B
+
+/*
+ *
+ * HW initialization
+ *
+ *
+ */
+static int __init rm680_sec_camera_init(void)
+{
+	if (gpio_request(SEC_CAMERA_RESET_GPIO, "sec_camera reset") != 0) {
+		printk(KERN_INFO "%s: unable to acquire secondary "
+		       "camera reset gpio\n", __func__);
+		return -ENODEV;
Quoted 8 lines

arch/arm/mach-omap2/board-rm680-camera.c line 68

Quoted 5 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +5 -0
+	}
+
+	/* XSHUTDOWN off, reset  */
+	gpio_direction_output(SEC_CAMERA_RESET_GPIO, 0);
+	gpio_set_value(SEC_CAMERA_RESET_GPIO, 0);

gpio_request_one() would be helpful here (and possibly in other locations in this file).

Moved to smiapp-core.c as suggested by Sylwester.

Quoted 9 lines

arch/arm/mach-omap2/board-rm680-camera.c line 75

Quoted 7 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +7 -0
+
+	return 0;
+}
+
+static int __init rm680_camera_hw_init(void)
+{
+	return rm680_sec_camera_init();

Maybe you could merge the two functions ?

Removed.

Quoted 177 lines
Quoted 177 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +17 -0
+}
+
+/*
+ *
+ * Main Camera Module EXTCLK
+ * Used by the sensor and the actuator driver.
+ *
+ */
+static struct camera_xclk {
+	u32 hz;
+	u32 lock;
+	u8 xclksel;
+} cameras_xclk;
+
+static DEFINE_MUTEX(lock_xclk);
+
+static int rm680_update_xclk(struct v4l2_subdev *subdev, u32 hz, u32

which, + u8 xclksel)

arch/arm/mach-omap2/board-rm680-camera.c new file +142 -0
+{
+	struct isp_device *isp = v4l2_dev_to_isp_device(subdev->v4l2_dev);
+	int ret;
+
+	mutex_lock(&lock_xclk);
+
+	if (which == RM680_SEC_SENSOR) {
+		if (cameras_xclk.xclksel == MAIN_CAMERA_XCLK) {
+			ret = -EBUSY;
+			goto done;
+		}
+	} else {
+		if (cameras_xclk.xclksel == SEC_CAMERA_XCLK) {
+			ret = -EBUSY;
+			goto done;
+		}
+	}
+
+	if (hz) {	/* Turn on */
+		cameras_xclk.lock |= which;
+		if (cameras_xclk.hz == 0) {
+			isp->platform_cb.set_xclk(isp, hz, xclksel);
+			cameras_xclk.hz = hz;
+			cameras_xclk.xclksel = xclksel;
+		}
+	} else {	/* Turn off */
+		cameras_xclk.lock &= ~which;
+		if (cameras_xclk.lock == 0) {
+			isp->platform_cb.set_xclk(isp, 0, xclksel);
+			cameras_xclk.hz = 0;
+			cameras_xclk.xclksel = 0;
+		}
+	}
+
+	ret = cameras_xclk.hz;
+
+done:
+	mutex_unlock(&lock_xclk);
+	return ret;
+}
+
+/*
+ *
+ * Main Camera Sensor
+ *
+ */
+
+static struct isp_csiphy_lanes_cfg rm696_main_camera_csi2_lanecfg = {
+	.clk = {
+		.pol = 1,
+		.pos = 2,
+	},
+	.data[0] = {
+		.pol = 1,
+		.pos = 1,
+	},
+	.data[1] = {
+		.pol = 1,
+		.pos = 3,
+	},
+};
+
+static struct isp_csiphy_lanes_cfg rm680_main_camera_csi2_lanecfg = {
+	.clk = {
+		.pol = 1,
+		.pos = 2,
+	},
+	.data[0] = {
+		.pol = 1,
+		.pos = 3,
+	},
+	.data[1] = {
+		.pol = 1,
+		.pos = 1,
+	},
+};
+
+static int rm680_main_camera_set_xclk(struct v4l2_subdev *sd, int hz)
+{
+	return rm680_update_xclk(sd, hz, RM680_PRI_SENSOR, MAIN_CAMERA_XCLK);
+}
+
+static struct smiapp_flash_strobe_parms rm680_main_camera_strobe_setup = {
+	.mode			= 0x0c,
+	.strobe_width_high_us	= 100000,
+	.strobe_delay		= 0,
+	.stobe_start_point	= 0,
+	.trigger		= 0,
+};
+
+static struct smiapp_platform_data rm696_main_camera_platform_data = {
+	.i2c_addr_dfl		= SMIAPP_DFL_I2C_ADDR,
+	.i2c_addr_alt		= SMIAPP_ALT_I2C_ADDR,
+	.nvm_size		= 16 * 64,
+	.ext_clk		= (9.6 * 1000 * 1000),
+	.lanes			= 2,
+	.op_sys_clock		= (s64 []){ 796800 / 2, 840000 / 2,
+					    1996800 / 2, 0 },
+	.csi_signalling_mode	= SMIAPP_CSI_SIGNALLING_MODE_CSI2,
+	.strobe_setup		= &rm680_main_camera_strobe_setup,
+	.set_xclk		= rm680_main_camera_set_xclk,
+};
+
+static struct smiapp_platform_data rm680_main_camera_platform_data = {
+	.i2c_addr_dfl		= SMIAPP_DFL_I2C_ADDR,
+	.i2c_addr_alt		= SMIAPP_ALT_I2C_ADDR,
+	.nvm_size		= 16 * 64,
+	.ext_clk		= (9.6 * 1000 * 1000),
+	.lanes			= 2,
+	.op_sys_clock		= (s64 []){ 840000 / 2, 1334400 / 2,
+					    1593600 / 2, 0 },
+	.csi_signalling_mode	= SMIAPP_CSI_SIGNALLING_MODE_CSI2,
+	.module_board_orient	= SMIAPP_MODULE_BOARD_ORIENT_180,
+	.strobe_setup		= &rm680_main_camera_strobe_setup,
+	.set_xclk		= rm680_main_camera_set_xclk,
+};
+
+/*
+ *
+ * SECONDARY CAMERA Sensor
+ *
+ */
+
+#define SEC_CAMERA_XCLK		ISP_XCLK_B
+
+static struct isp_csiphy_lanes_cfg rm680_sec_camera_csiphy_lanecfg = {
+	.clk = {
+		.pol = 0,
+		.pos = 1,
+	},
+	.data[0] = {
+		.pol = 0,
+		.pos = 2,
+	},
+};
+
+static int rm680_sec_camera_set_xclk(struct v4l2_subdev *sd, int hz)
+{
+	return rm680_update_xclk(sd, hz, RM680_SEC_SENSOR, SEC_CAMERA_XCLK);
+}
+
+static int rm680_sec_camera_set_xshutdown(struct v4l2_subdev *subdev, u8

set) +{

arch/arm/mach-omap2/board-rm680-camera.c new file +16 -0
+	gpio_set_value(SEC_CAMERA_RESET_GPIO, !!set);
+	return 0;
+}
+
+static struct smiapp_platform_data rm696_sec_camera_platform_data = {
+	.ext_clk		= (10.8 * 1000 * 1000),
+	.lanes			= 1,
+	.op_sys_clock		= (s64 []){ 13770 * 10, 0 },
+	.csi_signalling_mode	= SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK,
+	.module_board_orient	= SMIAPP_MODULE_BOARD_ORIENT_180,
+	.set_xclk		= rm680_sec_camera_set_xclk,
+	.set_xshutdown		= rm680_sec_camera_set_xshutdown,
+};
+
+static struct smiapp_platform_data rm680_sec_camera_platform_data = {
+	.ext_clk		= (10.8 * 1000 * 1000),
Quoted 8 lines

arch/arm/mach-omap2/board-rm680-camera.c line 257

Quoted 5 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +5 -0
+	.lanes			= 1,
+	.op_sys_clock		= (s64 []){ 11880 * 10, 0 },
+	.csi_signalling_mode	= SMIAPP_CSI_SIGNALLING_MODE_CCP2_DATA_CLOCK,
+	.set_xclk		= rm680_sec_camera_set_xclk,
+	.set_xshutdown		= rm680_sec_camera_set_xshutdown,

What about passing the GPIO number to the smiapp driver instead of using a callback function ?

Done.

Quoted 184 lines
Quoted 184 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +43 -0
+};
+
+/*
+ *
+ * Init all the modules
+ *
+ */
+
+#define CAMERA_I2C_BUS_NUM		2
+#define AD5836_I2C_BUS_NUM		2
+#define AS3645A_I2C_BUS_NUM		2
+
+static struct i2c_board_info rm696_camera_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO(SMIAPP_NAME, SMIAPP_ALT_I2C_ADDR),
+		.platform_data = &rm696_main_camera_platform_data,
+	},
+	{
+		I2C_BOARD_INFO(SMIAPP_NAME, SMIAPP_DFL_I2C_ADDR),
+		.platform_data = &rm696_sec_camera_platform_data,
+	},
+};
+
+static struct i2c_board_info rm680_camera_i2c_devices[] = {
+	{
+		I2C_BOARD_INFO(SMIAPP_NAME, SMIAPP_ALT_I2C_ADDR),
+		.platform_data = &rm680_main_camera_platform_data,
+	},
+	{
+		I2C_BOARD_INFO(SMIAPP_NAME, SMIAPP_DFL_I2C_ADDR),
+		.platform_data = &rm680_sec_camera_platform_data,
+	},
+};
+
+static struct isp_subdev_i2c_board_info rm696_camera_primary_subdevs[] = {
+	{
+		.board_info = &rm696_camera_i2c_devices[0],
+		.i2c_adapter_id = CAMERA_I2C_BUS_NUM,
+	},
+	{ NULL, 0, },
+};
+
+static struct isp_subdev_i2c_board_info rm696_camera_secondary_subdevs[] =

{ + {

arch/arm/mach-omap2/board-rm680-camera.c new file +15 -0
+		.board_info = &rm696_camera_i2c_devices[1],
+		.i2c_adapter_id = CAMERA_I2C_BUS_NUM,
+	},
+	{ NULL, 0, },
+};
+
+static struct isp_subdev_i2c_board_info rm680_camera_primary_subdevs[] = {
+	{
+		.board_info = &rm680_camera_i2c_devices[0],
+		.i2c_adapter_id = CAMERA_I2C_BUS_NUM,
+	},
+	{ NULL, 0, },
+};
+
+static struct isp_subdev_i2c_board_info rm680_camera_secondary_subdevs[] =

{ + {

arch/arm/mach-omap2/board-rm680-camera.c new file +91 -0
+		.board_info = &rm680_camera_i2c_devices[1],
+		.i2c_adapter_id = CAMERA_I2C_BUS_NUM,
+	},
+	{ NULL, 0, },
+};
+
+static struct isp_v4l2_subdevs_group rm696_camera_subdevs[] = {
+	{
+		.subdevs = rm696_camera_primary_subdevs,
+		.interface = ISP_INTERFACE_CSI2A_PHY2,
+		.bus = { .csi2 = {
+			.crc		= 1,
+			.vpclk_div	= 1,
+			.lanecfg	= &rm696_main_camera_csi2_lanecfg,
+		} },
+	},
+	{
+		.subdevs = rm696_camera_secondary_subdevs,
+		.interface = ISP_INTERFACE_CCP2B_PHY1,
+		.bus = { .ccp2 = {
+			.strobe_clk_pol	= 0,
+			.crc		= 0,
+			.ccp2_mode	= 0,
+			.phy_layer	= 0,
+			.vpclk_div	= 2,
+			.lanecfg	= &rm680_sec_camera_csiphy_lanecfg,
+		} },
+	},
+	{ NULL, 0, },
+};
+
+static struct isp_v4l2_subdevs_group rm680_camera_subdevs[] = {
+	{
+		.subdevs = rm680_camera_primary_subdevs,
+		.interface = ISP_INTERFACE_CSI2A_PHY2,
+		.bus = { .csi2 = {
+			.crc		= 1,
+			.vpclk_div	= 1,
+			.lanecfg	= &rm680_main_camera_csi2_lanecfg,
+		} },
+	},
+	{
+		.subdevs = rm680_camera_secondary_subdevs,
+		.interface = ISP_INTERFACE_CCP2B_PHY1,
+		.bus = { .ccp2 = {
+			.strobe_clk_pol	= 0,
+			.crc		= 0,
+			.ccp2_mode	= 0,
+			.phy_layer	= 0,
+			.vpclk_div	= 2,
+			.lanecfg	= &rm680_sec_camera_csiphy_lanecfg,
+		} },
+	},
+	{ NULL, 0, },
+};
+
+static struct isp_platform_data rm696_isp_platform_data = {
+	.subdevs = rm696_camera_subdevs,
+};
+
+static struct isp_platform_data rm680_isp_platform_data = {
+	.subdevs = rm680_camera_subdevs,
+};
+
+static inline int board_is_rm680(void)
+{
+	return (system_rev & 0x00f0) == 0x0020;
+}
+
+void __init rm680_camera_init(void)
+{
+	struct isp_platform_data *pdata;
+	int rval;
+
+	rval = rm680_camera_hw_init();
+	if (rval) {
+		printk(KERN_WARNING "%s: unable to initialise camera\n",
+		       __func__);
+		return;
+	}
+
+	if (board_is_rm680())
+		pdata = &rm680_isp_platform_data;
+	else
+		pdata = &rm696_isp_platform_data;
+
+	if (omap3_init_camera(pdata) < 0)
+		printk(KERN_WARNING
+		       "%s: unable to register camera platform device\n",
+		       __func__);
+}
(quoted diff) +0 -0

b/arch/arm/mach-omap2/board-rm680.c index a5bcc75..a1e33d4 100644

arch/arm/mach-omap2/board-rm680.c +25 -0
@@ -66,6 +66,43 @@ static struct platform_device rm680_vemmc_device = {
 	},
 };
 
+#define REGULATOR_INIT_DATA(_name, _min, _max, _apply, _ops_mask) \
+	static struct regulator_init_data _name##_data = { \
+		.constraints = { \
+			.name                   = #_name, \
+			.min_uV                 = _min, \
+			.max_uV                 = _max, \
+			.apply_uV               = _apply, \
+			.valid_modes_mask       = REGULATOR_MODE_NORMAL | \
+						REGULATOR_MODE_STANDBY, \
+			.valid_ops_mask         = _ops_mask, \
+		}, \
+		.num_consumer_supplies  = ARRAY_SIZE(_name##_consumers), \
+		.consumer_supplies      = _name##_consumers, \
+}
+#define REGULATOR_INIT_DATA_FIXED(_name, _voltage) \
+	REGULATOR_INIT_DATA(_name, _voltage, _voltage, true, \
+				REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_MODE)
+
+static struct regulator_consumer_supply rm680_vaux2_consumers[] = {
+	REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"),	/* OMAP ISP */
+	REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"),	/* OMAP ISP */
+	{
+		.supply		= "vaux2",
+	},
+};
Quoted 8 lines

arch/arm/mach-omap2/board-rm680.c static struct platform_device rm680_vemmc_device = { · line 98

Quoted 5 lines
arch/arm/mach-omap2/board-rm680.c +5 -0
+REGULATOR_INIT_DATA_FIXED(rm680_vaux2, 1800000);
+
+static struct regulator_consumer_supply rm680_vaux3_consumers[] = {
+	REGULATOR_SUPPLY("VANA", "2-0037"),	/* Main Camera Sensor */
+	REGULATOR_SUPPLY("VANA", "2-000e"),	/* Main Camera Lens */

The lens driver isn't upstream yet. We could keep the regulator supply definition to avoid forgetting it later though.

Sounds good to me.

Quoted 37 lines
Quoted 36 lines
arch/arm/mach-omap2/board-rm680.c +12 -0
+	REGULATOR_SUPPLY("VANA", "2-0010"),	/* Front Camera */
+	{
+		.supply		= "vaux3",
+	},
+};
+REGULATOR_INIT_DATA_FIXED(rm680_vaux3, 2800000);
+
 static struct platform_device *rm680_peripherals_devices[] __initdata = {
 	&rm680_vemmc_device,
 };
@@ -82,6 +119,8 @@ static struct twl4030_gpio_platform_data rm680_gpio_data
 = { static struct twl4030_platform_data rm680_twl_data = {
 	.gpio			= &rm680_gpio_data,
 	/* add rest of the children here */
+	.vaux2			= &rm680_vaux2_data,
+	.vaux3			= &rm680_vaux3_data,
 };
 
 static void __init rm680_i2c_init(void)
@@ -129,6 +168,8 @@ static struct omap_board_mux board_mux[] __initdata = {
 };
 #endif
 
+void rm680_camera_init(void);
+
 static void __init rm680_init(void)
 {
 	struct omap_sdrc_params *sdrc_params;
@@ -141,6 +182,7 @@ static void __init rm680_init(void)
 
 	usb_musb_init(NULL);
 	rm680_peripherals_init();
+	rm680_camera_init();
 }
 
 MACHINE_START(NOKIA_RM680, "Nokia RM-680 board")
Signature · 2 lines
Sakari Ailus
[email protected]
#72 lore raw

Re: [RFC 17/17] rm680: Add camera init

In reply to Sakari Ailus

Hi Sakari,

Review

Quoted 2 lines · Sakari Ailus
(quoted diff) +2 -0
+
+static int rm680_sec_camera_set_xshutdown(struct v4l2_subdev *subdev, u8 set)

It may be more efficient to just use u32.

Quoted 5 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +5 -0
+{
+	gpio_set_value(SEC_CAMERA_RESET_GPIO, !!set);
+	return 0;
+}
+

...

arch/arm/mach-omap2/board-rm680-camera.c line 394

Quoted 8 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +8 -0
+void __init rm680_camera_init(void)
+{
+	struct isp_platform_data *pdata;
+	int rval;
+
+	rval = rm680_camera_hw_init();
+	if (rval) {
+		printk(KERN_WARNING "%s: unable to initialise camera\n",

pr_warn is preferred for new code.

arch/arm/mach-omap2/board-rm680-camera.c line 405

Quoted 11 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +11 -0
+		       __func__);
+		return;
+	}
+
+	if (board_is_rm680())
+		pdata =&rm680_isp_platform_data;
+	else
+		pdata =&rm696_isp_platform_data;
+
+	if (omap3_init_camera(pdata)<  0)
+		printk(KERN_WARNING

pr_warn

Quoted 3 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +3 -0
+		       "%s: unable to register camera platform device\n",
+		       __func__);
+}

...

arch/arm/mach-omap2/board-rm680.c static struct platform_device rm680_vemmc_device = { · line 92

Quoted 6 lines
arch/arm/mach-omap2/board-rm680.c +6 -0
+static struct regulator_consumer_supply rm680_vaux2_consumers[] = {
+	REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"),	/* OMAP ISP */
+	REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"),	/* OMAP ISP */
+	{
+		.supply		= "vaux2",
+	},

Could also be
REGULATOR_SUPPLY("vaux2", NULL),

arch/arm/mach-omap2/board-rm680.c static struct platform_device rm680_vemmc_device = { · line 102

Quoted 10 lines
arch/arm/mach-omap2/board-rm680.c +10 -0
+};
+REGULATOR_INIT_DATA_FIXED(rm680_vaux2, 1800000);
+
+static struct regulator_consumer_supply rm680_vaux3_consumers[] = {
+	REGULATOR_SUPPLY("VANA", "2-0037"),	/* Main Camera Sensor */
+	REGULATOR_SUPPLY("VANA", "2-000e"),	/* Main Camera Lens */
+	REGULATOR_SUPPLY("VANA", "2-0010"),	/* Front Camera */
+	{
+		.supply		= "vaux3",
+	},

and REGULATOR_SUPPLY("vaux3", NULL),

Quoted 1 line

+};

--
Regards,
Sylwester

#73 lore raw

Re: [RFC 17/17] rm680: Add camera init

Hi Sylwester,

Thanks for the review!

Quoted 6 lines · Sylwester Nawrocki
Quoted 3 lines · Sakari Ailus
(quoted diff) +2 -0
+
+static int rm680_sec_camera_set_xshutdown(struct v4l2_subdev *subdev,

u8 set)

It may be more efficient to just use u32.

The function got removed already. ;-)

Quoted 6 lines
Quoted 5 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +5 -0
+{
+    gpio_set_value(SEC_CAMERA_RESET_GPIO, !!set);
+    return 0;
+}
+

...

Quoted 10 lines

arch/arm/mach-omap2/board-rm680-camera.c line 394

Quoted 8 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +8 -0
+void __init rm680_camera_init(void)
+{
+    struct isp_platform_data *pdata;
+    int rval;
+
+    rval = rm680_camera_hw_init();
+    if (rval) {
+        printk(KERN_WARNING "%s: unable to initialise camera\n",

pr_warn is preferred for new code.

Fixed.

Quoted 5 lines
Quoted 5 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +5 -0
+               __func__);
+        return;
+    }
+
+    if (board_is_rm680())
Quoted 8 lines

arch/arm/mach-omap2/board-rm680-camera.c line 405

Quoted 6 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +6 -0
+        pdata =&rm680_isp_platform_data;
+    else
+        pdata =&rm696_isp_platform_data;
+
+    if (omap3_init_camera(pdata)<  0)
+        printk(KERN_WARNING

pr_warn

Ditto.

Quoted 11 lines
Quoted 3 lines
arch/arm/mach-omap2/board-rm680-camera.c new file +3 -0
+               "%s: unable to register camera platform device\n",
+               __func__);
+}

...

arch/arm/mach-omap2/board-rm680.c static struct platform_device rm680_vemmc_device = { · line 92

Quoted 6 lines
arch/arm/mach-omap2/board-rm680.c +6 -0
+static struct regulator_consumer_supply rm680_vaux2_consumers[] = {
+    REGULATOR_SUPPLY("VDD_CSIPHY1", "omap3isp"),    /* OMAP ISP */
+    REGULATOR_SUPPLY("VDD_CSIPHY2", "omap3isp"),    /* OMAP ISP */
+    {
+        .supply        = "vaux2",
+    },
Quoted 2 lines

Could also be
REGULATOR_SUPPLY("vaux2", NULL),

Fixed.

Quoted 4 lines
Quoted 4 lines
arch/arm/mach-omap2/board-rm680.c +4 -0
+};
+REGULATOR_INIT_DATA_FIXED(rm680_vaux2, 1800000);
+
+static struct regulator_consumer_supply rm680_vaux3_consumers[] = {
Quoted 8 lines

arch/arm/mach-omap2/board-rm680.c static struct platform_device rm680_vemmc_device = { · line 102

Quoted 6 lines
arch/arm/mach-omap2/board-rm680.c +6 -0
+    REGULATOR_SUPPLY("VANA", "2-0037"),    /* Main Camera Sensor */
+    REGULATOR_SUPPLY("VANA", "2-000e"),    /* Main Camera Lens */
+    REGULATOR_SUPPLY("VANA", "2-0010"),    /* Front Camera */
+    {
+        .supply        = "vaux3",
+    },

and REGULATOR_SUPPLY("vaux3", NULL),

Ditto.

Quoted 6 lines
Quoted 1 line

+};

Signature · 2 lines
Regards,
Sylwester
Signature · 2 lines
Sakari Ailus
[email protected]
#74 lore raw

PATCH 1/1 Support integer menus.

In reply to Sakari Ailus
---
 yavta.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)
yavta.c +9 -3
index c0e9acb..9b8a80e 100644
@@ -551,6 +551,7 @@ static int video_enable(struct device *dev, int enable)
 }
 
 static void video_query_menu(struct device *dev, unsigned int id,
+			     unsigned int type,
 			     unsigned int min, unsigned int max)
 {
 	struct v4l2_querymenu menu;
@@ -562,7 +563,10 @@ static void video_query_menu(struct device *dev, unsigned int id,
 		if (ret < 0)
 			continue;
 
-		printf("  %u: %.32s\n", menu.index, menu.name);
+		if (type == V4L2_CTRL_TYPE_MENU)
+			printf("  %u: %.32s\n", menu.index, menu.name);
+		else
+			printf("  %u: %lld\n", menu.index, menu.value);
 	};
 }
 
@@ -607,8 +611,10 @@ static void video_list_controls(struct device *dev)
 			query.id, query.name, query.minimum, query.maximum,
 			query.step, query.default_value, value);
 
-		if (query.type == V4L2_CTRL_TYPE_MENU)
-			video_query_menu(dev, query.id, query.minimum, query.maximum);
+		if (query.type == V4L2_CTRL_TYPE_MENU ||
+		    query.type == V4L2_CTRL_TYPE_INTEGER_MENU)
+			video_query_menu(dev, query.id, query.type,
+					 query.minimum, query.maximum);
 
 		nctrls++;
 	}
Signature · 1 line
1.7.2.5
#75 lore raw

Re: [yavta PATCH 1/1] Support integer menus.

Hi Sakari,

Thanks for the patch.

Quoted 30 lines · On Wednesday 28 December 2011 10:47:01 Sakari Ailus wrote:
---
 yavta.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)
yavta.c +5 -1
index c0e9acb..9b8a80e 100644
@@ -551,6 +551,7 @@ static int video_enable(struct device *dev, int enable)
 }
 
 static void video_query_menu(struct device *dev, unsigned int id,
+			     unsigned int type,
 			     unsigned int min, unsigned int max)
 {
 	struct v4l2_querymenu menu;
@@ -562,7 +563,10 @@ static void video_query_menu(struct device *dev,
 unsigned int id, if (ret < 0)
 			continue;
 
-		printf("  %u: %.32s\n", menu.index, menu.name);
+		if (type == V4L2_CTRL_TYPE_MENU)
+			printf("  %u: %.32s\n", menu.index, menu.name);
+		else
+			printf("  %u: %lld\n", menu.index, menu.value);
 	};
 }
 

yavta.c static void video_list_controls(struct device *dev) · line 617

Quoted 9 lines
yavta.c +4 -2
@@ -607,8 +611,10 @@ static void video_list_controls(struct device *dev)
 			query.id, query.name, query.minimum, query.maximum,
 			query.step, query.default_value, value);
 
-		if (query.type == V4L2_CTRL_TYPE_MENU)
-			video_query_menu(dev, query.id, query.minimum, query.maximum);
+		if (query.type == V4L2_CTRL_TYPE_MENU ||
+		    query.type == V4L2_CTRL_TYPE_INTEGER_MENU)
+			video_query_menu(dev, query.id, query.type,
+					 query.minimum, query.maximum);

What about passing &query to the function instead ?

Quoted 3 lines
yavta.c +0 -0
 		nctrls++;
 	}
Signature · 3 lines
Regards,

Laurent Pinchart