Skip to contentSkip to conversation

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

PATCH In review Sakari Ailus 6 participants 93 messages Mar 6, 2012 – May 14, 2012

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

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

Hi everyone,

This the fifth version of my patchset that contains:

- Integer menu controls [2],
- Selection IOCTL for subdevs [3],
- Sensor control changes [5,7],
- link_validate() media entity and V4L2 subdev pad ops,
- OMAP 3 ISP driver improvements [4],
- SMIA++ sensor driver,
- rm680/rm696 board code (a.k.a Nokia N9 and N950) and
- Other V4L2 and media improvements (see individual patches)

The Docbook documentation in HTML format can be found in [15] (v3 documentation available in [11] and v4 in [13]).

The issue with "ACTIVE" target names still needs to be addressed. The current proposal is "CURRENT". To be discussed on IRC.

Changes to version 4 [16]:

- V4L2 / V4L2 subdev
- Documentation
- Spelling fixes
- Red lines in diagrams dotted instead of solid
- Proper ordering of raw bayer formats

- SMIA++ driver
- PLL code separated from the actual driver
- Source pads are always zero now
- Error handling fixes in nvm reading
- Try format pixel code handling fixes
- Miscellaneous code cleanups

- Media controller
- Dropped the patch to find entities; moved to omap3isp driver instead

- OMAP 3 ISP
- Find out external entity's pad number, don't assume zero (new patch)
- Small cleanups
- Entities in pipeline stored in struct isp_pipeline

Changes to version 3 [12] include:

- OMAP 3 ISP
- Rework ISP driver patches
- Remove code from isp_video_pipeline_validate in same patch as the functionality is added elsewhere (old patch to remove leftovers dropped)
- isp_video_streamon() error handling cleanups
- All pipeline validation performed before any s_straem subdev ops
- Resizer data rate check moved to link validation
- CCDC rate checked in isp_video_check_external_subdeva()
- Formats checked during link validation
- Remove means to set pixel rate (new patch)
- Don't set link_validate pad ops where the default is sufficient

- Media controller
- media_entity_pipeline_start() collects information on entities in pipeline
- link validation error handling fix

- V4L2 / V4L2 subdev
- Less confusing selection example diagrams
- Selection documentation improvements (as also suggested by Laurent)

- SMIA++ driver
- Fixes according to Laurent's suggestions [14]
- Locking fixes and power handling cleanups

Changes to version 2 [10] include:

- V4L2
- Image source controls
- Documentation no longer refers to "pixel clock" in v4l2_mbus_framefmt (this should have been the last reference to those!!)
- Capitalise first letters in control names
- Selections
- Use hex numbers for targets
- Return NULL instead of invalid pointer when accessing non-existend pads in v4l2_subdev_get_try_{format,crop,compose} (new patch)
- Put link validation definitions in v4l2-subdev.h behind

    #ifdef CONFIG_MEDIA_CONTROLLER ... #endif

- Spelling fixes (selections and 4cc guidelines)
- Change vdev_to_v4l2_subdev() return type to struct v4l2_subdev * (new patch)

- SMIA++ driver
- Clock tree calculation fixes
- Control handler setup usage fixes at smiapp_open()
- Don't access non-existent pads

Changes to version 1 [8] include:

- OMAP 3 ISP driver
- Swapped order of csi receiver's lane definitions
- Rewrote omap 3 isp link validation patches almost completely
- Information on connected external entity collected to isp_pipeline
- Information collected during link checking and used at streamon

- Media entity link validation
- Error handling fixes

- SMIA++ driver
- Selection API bugfixes
- Report correct pixel order right from boot
- Move link rate control to subdev connected to subdev external to the sensor (e.g. ISP's CSI-2 receiver)
- Introduce proper serialisation
- Deny changing some controls when streaming (flipping and link rate)
- Control handler setup moved from streamon time to first subdev open
- There is no source compose target
- Bugfixes

- Media bus pixel codes
- Documentation fix for dpcm compressed formats
- Added patch for 4CC guidelines (raw bayer only for now)

- Selections
- Improved selections documentation
- Added more selections examples
- Compose target is not available on source pads anymore [9]
- Dropped default targets

- V4L2
- Add documentation on link_validate()
- link_validate() and relater functions depends on
CONFIG_MEDIA_CONTROLLER
- Skip link validation for links on which stream_count was non-zero
- Do not validate link if entity's stream count is non-zero
- Use v4l2_subdev_link_validate_default() if no link_validate pad op
is set
- Allow changing control handler mutex: this enables a driver to provide multiple subdevs but use only one mutex. Default mutex (part of struct v4l2_ctrl_handler) is set in v4l2_ctrl_handler_init().
- Split image source class into two: image source and image processing

Changes to the RFC v1 [6] include:

- Integer controls:
- Target Linux 3.4 instead of 3.3
- Proper control type check in querymenu
- vivi compile fixes

- Subdev selections
- Pad try fields combined to single struct
- Correctly set sel.which based on crop->which in crop fall-back

- Subdev selection documentation
- Better explanation on image processing in subdevs
- Added a diagram to visualise subdev configuration
- Fixed DocBook syntax issues
- Mark VIDIOC_SUBDEV_S_CROP and VIDIOC_SUBDEV_G_CROP obsolete

- Pixel rate
- Pixel rate is now a 64-bit control, not part of v4l2_mbus_framefmt
- Unit for pixel rate is pixels / second
- Pixel rate is read-only

- Link frequency is now in Hz --- documented as such also

- Link validation instead of pipeline validation
- Each link is validated by calling link_validate op
- Added link validation op to media_entity_ops
- Link validation op in pad ops makes this easy for subdev drivers
- media_entity_pipeline_start() may return an error code now
- This might affect other drivers, but will warn in compilation. No adverse effects are caused if the driver does not use link_validate().

- OMAP 3 ISP
- Make lanecfg as part of the platform data structure, not pointer
- Document lane configuration structures
- Link validation moved to respective subdev drivers from ispvideo.c
- isp_validate_pipeline() removed

- SMIA++ driver
- Update pixel order based on vflip and hflip
- Cleanups in the main driver, register definitions and PLL code
- Depend on V4L2_V4L2_SUBDEV_API and MEDIA_CONTROLLER
- Use pr_* macros instead of printk
- Improved error handling for i2c_transfer()
- Removed useless definitions
- Don't access try crop / compose directly but use helper functions
- Add xshutdown to platform data
- Move driver under smiapp directory

- rm680 board code
- Use REGULATOR_SUPPLY() where possible
- Removed printk()'s
- Don't include private smiapp headers

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

[6] http://www.spinics.net/lists/linux-media/msg41765.html

[7] http://www.spinics.net/lists/linux-media/msg42848.html

[8] http://www.spinics.net/lists/linux-media/msg42991.html

[9] http://www.spinics.net/lists/linux-media/msg43810.html

[10] http://www.spinics.net/lists/linux-media/msg43888.html

[11] http://www.retiisi.org.uk/v4l2/tmp/media_api/

[12] http://www.spinics.net/lists/linux-media/msg44405.html

[13] http://www.retiisi.org.uk/v4l2/tmp/media_api2/

[14] http://www.spinics.net/lists/linux-media/msg44704.html

[15] http://wwww.retiisi.org.uk/v4l2/tmp/media_api3/

[16] http://www.spinics.net/lists/linux-media/msg44843.html

Kind regards,

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

PATCH v5 1/35 v4l: Introduce integer menu controls

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 |   74 +++++++++++++++++++++++++++++---------
 include/linux/videodev2.h        |    6 +++-
 include/media/v4l2-ctrls.h       |    6 +++-
 3 files changed, 67 insertions(+), 19 deletions(-)
drivers/media/video/v4l2-ctrls.c +57 -17
index 9091172..f0484bd 100644
@@ -828,7 +828,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;
@@ -1059,10 +1060,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;
 
@@ -1090,6 +1094,7 @@ static int validate_new(const struct v4l2_ctrl *ctrl, struct v4l2_ext_control *c
 	case V4L2_CTRL_TYPE_INTEGER:
 	case V4L2_CTRL_TYPE_BOOLEAN:
 	case V4L2_CTRL_TYPE_MENU:
+	case V4L2_CTRL_TYPE_INTEGER_MENU:
 	case V4L2_CTRL_TYPE_BITMASK:
 	case V4L2_CTRL_TYPE_BUTTON:
 	case V4L2_CTRL_TYPE_CTRL_CLASS:
@@ -1319,7 +1324,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;
@@ -1332,6 +1338,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;
@@ -1342,6 +1349,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);
@@ -1376,7 +1384,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;
 
@@ -1403,6 +1414,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;
@@ -1414,18 +1426,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;
@@ -1442,12 +1460,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);
 
@@ -1469,7 +1488,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);
 
@@ -1633,6 +1652,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;
@@ -1769,7 +1791,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;
@@ -1799,16 +1822,33 @@ int v4l2_querymenu(struct v4l2_ctrl_handler *hdl, struct v4l2_querymenu *qm)
 
 	qm->reserved = 0;
 	/* Sanity checks */
-	if (ctrl->qmenu == NULL ||
-	    i < ctrl->minimum || i > ctrl->maximum)
+	switch (ctrl->type) {
+	case V4L2_CTRL_TYPE_MENU:
+		if (ctrl->qmenu == NULL)
+			return -EINVAL;
+		break;
+	case V4L2_CTRL_TYPE_INTEGER_MENU:
+		if (ctrl->qmenu_int == NULL)
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (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 {
+		qm->value = ctrl->qmenu_int[i];
+	}
 	return 0;
 }
 EXPORT_SYMBOL(v4l2_querymenu);
include/linux/videodev2.h +5 -1
index b739d7d..e3c6302 100644
@@ -1150,6 +1150,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 */
@@ -1169,7 +1170,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 3dbd066..533315b 100644
@@ -130,7 +130,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;
@@ -220,6 +223,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

PATCH v5 2/35 v4l: Document integer menu controls

In reply to Sakari Ailus
---
 Documentation/DocBook/media/v4l/compat.xml         |   10 +++++
 Documentation/DocBook/media/v4l/v4l2.xml           |    6 +++
 .../DocBook/media/v4l/vidioc-queryctrl.xml         |   39 +++++++++++++++++++-
 3 files changed, 53 insertions(+), 2 deletions(-)
Documentation/DocBook/media/v4l/compat.xml +10 -0
index c93298f..8cd5c96 100644
@@ -2400,6 +2400,16 @@ details.</para>
       </orderedlist>
     </section>
 
+    <section>
+      <title>V4L2 in Linux 3.4</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 +6 -0
index dcf9e33..ff11a13 100644
@@ -128,6 +128,12 @@ structs, ioctls) must be noted in more detail in the history chapter
 applications. -->
 
       <revision>
+	<revnumber>3.4</revnumber>
+	<date>2012-01-26</date>
+	<authorinitials>sa</authorinitials>
+	<revremark>Added V4L2_CTRL_TYPE_INTEGER_MENU.</revremark>
+      </revision>
+      <revision>
 	<revnumber>3.3</revnumber>
 	<date>2012-01-11</date>
 	<authorinitials>hv</authorinitials>
Documentation/DocBook/media/v4l/vidioc-queryctrl.xml +37 -2
index 36660d3..505f020 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
#3 lore raw

PATCH v5 3/35 vivi: Add an integer menu test control

In reply to Sakari Ailus

Add an integer menu test control for the vivi driver.

---
 drivers/media/video/vivi.c |   22 ++++++++++++++++++++++
 1 files changed, 22 insertions(+), 0 deletions(-)
drivers/media/video/vivi.c +22 -0
index 5e8b071..d75a1e4 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 %lld, value %d ",
+			dev->int_menu->qmenu_int[dev->int_menu->cur.val],
+			dev->int_menu->cur.val);
+	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) {
@@ -1165,6 +1170,22 @@ static const struct v4l2_ctrl_config vivi_ctrl_bitmask = {
 	.step = 0,
 };
 
+static const s64 vivi_ctrl_int_menu_values[] = {
+	1, 1, 2, 3, 5, 8, 13, 21, 42,
+};
+
+static const struct v4l2_ctrl_config vivi_ctrl_int_menu = {
+	.ops = &vivi_ctrl_ops,
+	.id = VIVI_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,
@@ -1275,6 +1296,7 @@ static int __init vivi_create_instance(int inst)
 	dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL);
 	dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL);
 	dev->bitmask = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_bitmask, NULL);
+	dev->int_menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int_menu, NULL);
 	if (hdl->error) {
 		ret = hdl->error;
 		goto unreg_dev;
Signature · 1 line
1.7.2.5
#4 lore raw

PATCH v5 4/35 v4l: VIDIOC_SUBDEV_S_SELECTION and VIDIOC_SUBDEV_G_SELECTION IOCTLs

In reply to Sakari Ailus

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 |   42 ++++++++++++++++++++++++++++--------
 include/linux/v4l2-subdev.h       |   41 ++++++++++++++++++++++++++++++++++++
 include/media/v4l2-subdev.h       |   21 +++++++++++++++---
 3 files changed, 90 insertions(+), 14 deletions(-)
drivers/media/video/v4l2-subdev.c +32 -10
index 6fe88e9..7d22538 100644
@@ -35,14 +35,9 @@
 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))
-			      * sd->entity.num_pads, GFP_KERNEL);
-	if (fh->try_fmt == NULL)
+	fh->pad = kzalloc(sizeof(*fh->pad) * sd->entity.num_pads, GFP_KERNEL);
+	if (fh->pad == NULL)
 		return -ENOMEM;
-
-	fh->try_crop = (struct v4l2_rect *)
-		(fh->try_fmt + sd->entity.num_pads);
 #endif
 	return 0;
 }
@@ -50,9 +45,8 @@ static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
 static void subdev_fh_free(struct v4l2_subdev_fh *fh)
 {
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
-	kfree(fh->try_fmt);
-	fh->try_fmt = NULL;
-	fh->try_crop = NULL;
+	kfree(fh->pad);
+	fh->pad = NULL;
 #endif
 }
 
@@ -293,6 +287,34 @@ 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->which != V4L2_SUBDEV_FORMAT_TRY &&
+		    sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+			return -EINVAL;
+
+		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->which != V4L2_SUBDEV_FORMAT_TRY &&
+		    sel->which != V4L2_SUBDEV_FORMAT_ACTIVE)
+			return -EINVAL;
+
+		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 +41 -0

52 lines not on this page · raw message

include/media/v4l2-subdev.h +17 -4
index f0f3358..feab950 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 {
@@ -549,8 +553,11 @@ struct v4l2_subdev {
 struct v4l2_subdev_fh {
 	struct v4l2_fh vfh;
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
-	struct v4l2_mbus_framefmt *try_fmt;
-	struct v4l2_rect *try_crop;
+	struct {
+		struct v4l2_mbus_framefmt try_fmt;
+		struct v4l2_rect try_crop;
+		struct v4l2_rect try_compose;
+	} *pad;
 #endif
 };
 
@@ -561,13 +568,19 @@ struct v4l2_subdev_fh {
 static inline struct v4l2_mbus_framefmt *
 v4l2_subdev_get_try_format(struct v4l2_subdev_fh *fh, unsigned int pad)
 {
-	return &fh->try_fmt[pad];
+	return &fh->pad[pad].try_fmt;
 }
 
 static inline struct v4l2_rect *
 v4l2_subdev_get_try_crop(struct v4l2_subdev_fh *fh, unsigned int pad)
 {
-	return &fh->try_crop[pad];
+	return &fh->pad[pad].try_crop;
+}
+
+static inline struct v4l2_rect *
+v4l2_subdev_get_try_compose(struct v4l2_subdev_fh *fh, unsigned int pad)
+{
+	return &fh->pad[pad].try_compose;
 }
 #endif
 
Signature · 1 line
1.7.2.5
#5 lore raw

PATCH v5 5/35 v4l: vdev_to_v4l2_subdev() should have return type "struct v4l2_subdev *"

In reply to Sakari Ailus

vdev_to_v4l2_subdev() should return struct v4l2_subdev *, not void *. Fix this.

---
 include/media/v4l2-subdev.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
include/media/v4l2-subdev.h +1 -1
index feab950..bcaf6b8 100644
@@ -545,7 +545,7 @@ struct v4l2_subdev {
 #define media_entity_to_v4l2_subdev(ent) \
 	container_of(ent, struct v4l2_subdev, entity)
 #define vdev_to_v4l2_subdev(vdev) \
-	video_get_drvdata(vdev)
+	((struct v4l2_subdev *)video_get_drvdata(vdev))
 
 /*
  * Used for storing subdev information per file handle
Signature · 1 line
1.7.2.5
#6 lore raw

PATCH v5 6/35 v4l: Check pad number in get try pointer functions

In reply to Sakari Ailus

Unify functions to get try pointers and validate the pad number accessed by the user.

---
 include/media/v4l2-subdev.h |   30 +++++++++++++-----------------
 1 files changed, 13 insertions(+), 17 deletions(-)
include/media/v4l2-subdev.h +13 -17
index bcaf6b8..7e85035 100644
@@ -565,23 +565,19 @@ struct v4l2_subdev_fh {
 	container_of(fh, struct v4l2_subdev_fh, vfh)
 
 #if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
-static inline struct v4l2_mbus_framefmt *
-v4l2_subdev_get_try_format(struct v4l2_subdev_fh *fh, unsigned int pad)
-{
-	return &fh->pad[pad].try_fmt;
-}
-
-static inline struct v4l2_rect *
-v4l2_subdev_get_try_crop(struct v4l2_subdev_fh *fh, unsigned int pad)
-{
-	return &fh->pad[pad].try_crop;
-}
-
-static inline struct v4l2_rect *
-v4l2_subdev_get_try_compose(struct v4l2_subdev_fh *fh, unsigned int pad)
-{
-	return &fh->pad[pad].try_compose;
-}
+#define __V4L2_SUBDEV_MK_GET_TRY(rtype, fun_name, field_name)		\
+	static inline struct rtype *					\
+	v4l2_subdev_get_try_##fun_name(struct v4l2_subdev_fh *fh,	\
+				       unsigned int pad)		\
+	{								\
+		BUG_ON(unlikely(pad >= vdev_to_v4l2_subdev(		\
+					fh->vfh.vdev)->entity.num_pads)); \
+		return &fh->pad[pad].field_name;			\
+	}
+
+__V4L2_SUBDEV_MK_GET_TRY(v4l2_mbus_framefmt, format, try_fmt)
+__V4L2_SUBDEV_MK_GET_TRY(v4l2_rect, crop, try_compose)
+__V4L2_SUBDEV_MK_GET_TRY(v4l2_rect, compose, try_compose)
 #endif
 
 extern const struct v4l2_file_operations v4l2_subdev_fops;
Signature · 1 line
1.7.2.5
#7 lore raw

PATCH v5 7/35 v4l: Support s_crop and g_crop through s/g_selection

In reply to Sakari Ailus

Fall back 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 7d22538..eda34cd 100644
@@ -228,6 +228,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)
@@ -236,11 +238,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 = crop->which;
+		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)
@@ -249,7 +267,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 = crop->which;
+		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
#8 lore raw

PATCH v5 8/35 v4l: Add subdev selections documentation: svg and dia files

In reply to Sakari Ailus

Add svga and dia files for V4L2 subdev selections documentation.

---
 .../media/v4l/subdev-image-processing-crop.dia     |  614 ++++++++
 .../media/v4l/subdev-image-processing-crop.svg     |   63 +
 .../media/v4l/subdev-image-processing-full.dia     | 1588 ++++++++++++++++++++
 .../media/v4l/subdev-image-processing-full.svg     |  163 ++
 ...ubdev-image-processing-scaling-multi-source.dia | 1152 ++++++++++++++
 ...ubdev-image-processing-scaling-multi-source.svg |  116 ++
 6 files changed, 3696 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/subdev-image-processing-crop.dia
 create mode 100644 Documentation/DocBook/media/v4l/subdev-image-processing-crop.svg
 create mode 100644 Documentation/DocBook/media/v4l/subdev-image-processing-full.dia
 create mode 100644 Documentation/DocBook/media/v4l/subdev-image-processing-full.svg
 create mode 100644 Documentation/DocBook/media/v4l/subdev-image-processing-scaling-multi-source.dia
 create mode 100644 Documentation/DocBook/media/v4l/subdev-image-processing-scaling-multi-source.svg
Documentation/DocBook/media/v4l/subdev-image-processing-crop.dia new file +614 -0
new file mode 100644
index 0000000..e32ba53
@@ -0,0 +1,614 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
+  <dia:diagramdata>
+    <dia:attribute name="background">
+      <dia:color val="#ffffff"/>
+    </dia:attribute>
+    <dia:attribute name="pagebreak">
+      <dia:color val="#000099"/>
+    </dia:attribute>
+    <dia:attribute name="paper">
+      <dia:composite type="paper">
+        <dia:attribute name="name">
+          <dia:string>#A4#</dia:string>
+        </dia:attribute>
+        <dia:attribute name="tmargin">
+          <dia:real val="2.8222000598907471"/>
+        </dia:attribute>
+        <dia:attribute name="bmargin">
+          <dia:real val="2.8222000598907471"/>
+        </dia:attribute>
+        <dia:attribute name="lmargin">
+          <dia:real val="2.8222000598907471"/>
+        </dia:attribute>
+        <dia:attribute name="rmargin">
+          <dia:real val="2.8222000598907471"/>
+        </dia:attribute>
+        <dia:attribute name="is_portrait">
+          <dia:boolean val="false"/>
+        </dia:attribute>
+        <dia:attribute name="scaling">
+          <dia:real val="0.49000000953674316"/>
+        </dia:attribute>
+        <dia:attribute name="fitto">
+          <dia:boolean val="false"/>
+        </dia:attribute>
+      </dia:composite>
+    </dia:attribute>
+    <dia:attribute name="grid">
+      <dia:composite type="grid">
+        <dia:attribute name="width_x">
+          <dia:real val="1"/>
+        </dia:attribute>
+        <dia:attribute name="width_y">
+          <dia:real val="1"/>
+        </dia:attribute>
+        <dia:attribute name="visible_x">
+          <dia:int val="1"/>
+        </dia:attribute>
+        <dia:attribute name="visible_y">
+          <dia:int val="1"/>
+        </dia:attribute>
+        <dia:composite type="color"/>
+      </dia:composite>
+    </dia:attribute>
+    <dia:attribute name="color">
+      <dia:color val="#d8e5e5"/>
+    </dia:attribute>
+    <dia:attribute name="guides">
+      <dia:composite type="guides">
+        <dia:attribute name="hguides"/>
+        <dia:attribute name="vguides"/>
+      </dia:composite>
+    </dia:attribute>
+  </dia:diagramdata>
+  <dia:layer name="Background" visible="true" active="true">
+    <dia:object type="Standard - Box" version="0" id="O0">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-0.4,6.5"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-0.45,6.45;23.1387,16.2"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-0.4,6.5"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="23.48871579904775"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="9.6500000000000004"/>
+      </dia:attribute>
+      <dia:attribute name="border_width">
+        <dia:real val="0.10000000149011612"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - Box" version="0" id="O1">
+      <dia:attribute name="obj_pos">
+        <dia:point val="0.225,9.45"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="0.175,9.4;8.225,14.7"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="0.225,9.45"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="7.9499999999999975"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="5.1999999999999975"/>
+      </dia:attribute>
+      <dia:attribute name="border_width">
+        <dia:real val="0.10000000149011612"/>
+      </dia:attribute>
+      <dia:attribute name="border_color">
+        <dia:color val="#a52a2a"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - Box" version="0" id="O2">
+      <dia:attribute name="obj_pos">
+        <dia:point val="3.175,10.55"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="3.125,10.5;7.925,14.45"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="3.175,10.55"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="4.6999999999999975"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="3.8499999999999979"/>
+      </dia:attribute>
+      <dia:attribute name="border_width">
+        <dia:real val="0.10000000149011612"/>
+      </dia:attribute>
+      <dia:attribute name="border_color">
+        <dia:color val="#0000ff"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - Text" version="1" id="O3">
+      <dia:attribute name="obj_pos">
+        <dia:point val="3.725,11.3875"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="3.725,10.7925;6.6025,13.14"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#sink
+crop
+selection#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="0.80000000000000004"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="3.725,11.3875"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#0000ff"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+      <dia:attribute name="valign">
+        <dia:enum val="3"/>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - Text" version="1" id="O4">
+      <dia:attribute name="obj_pos">
+        <dia:point val="1.475,7.9"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="1.475,7.305;1.475,8.0525"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>##</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="0.80000000000000004"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="1.475,7.9"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+      <dia:attribute name="valign">
+        <dia:enum val="3"/>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - Text" version="1" id="O5">
+      <dia:attribute name="obj_pos">
+        <dia:point val="0.426918,7.89569"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="0.426918,7.30069;3.90942,8.84819"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#sink media
+bus format#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="0.80000000000000004"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="0.426918,7.89569"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#a52a2a"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+      <dia:attribute name="valign">
+        <dia:enum val="3"/>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - Text" version="1" id="O6">
+      <dia:attribute name="obj_pos">
+        <dia:point val="17.4887,7.75"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="17.4887,7.155;21.8112,8.7025"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#source media
+bus format#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="0.80000000000000004"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="17.4887,7.75"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#8b6914"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+      <dia:attribute name="valign">
+        <dia:enum val="3"/>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - Box" version="0" id="O7">
+      <dia:attribute name="obj_pos">
+        <dia:point val="17.5244,9.5417"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="17.4744,9.4917;22.2387,13.35"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="17.5244,9.5417"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="4.6643157990477508"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="3.758300000000002"/>
+      </dia:attribute>
+      <dia:attribute name="border_width">
+        <dia:real val="0.10000000149011612"/>
+      </dia:attribute>
+      <dia:attribute name="border_color">
+        <dia:color val="#8b6914"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - Line" version="0" id="O8">
+      <dia:attribute name="obj_pos">
+        <dia:point val="17.5244,13.3"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="3.12132,13.2463;17.5781,14.4537"/>
+      </dia:attribute>
+      <dia:attribute name="conn_endpoints">
+        <dia:point val="17.5244,13.3"/>
+        <dia:point val="3.175,14.4"/>
+      </dia:attribute>
+      <dia:attribute name="numcp">
+        <dia:int val="1"/>
+      </dia:attribute>
+      <dia:attribute name="line_color">
+        <dia:color val="#e60505"/>
+      </dia:attribute>
+      <dia:attribute name="line_style">
+        <dia:enum val="4"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O7" connection="5"/>
+        <dia:connection handle="1" to="O2" connection="5"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Standard - Line" version="0" id="O9">
+      <dia:attribute name="obj_pos">
+        <dia:point val="17.5244,9.5417"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="3.12162,9.48832;17.5778,10.6034"/>
+      </dia:attribute>
+      <dia:attribute name="conn_endpoints">
+        <dia:point val="17.5244,9.5417"/>
+        <dia:point val="3.175,10.55"/>
+      </dia:attribute>
+      <dia:attribute name="numcp">
+        <dia:int val="1"/>
+      </dia:attribute>
+      <dia:attribute name="line_color">
+        <dia:color val="#e60505"/>
+      </dia:attribute>
+      <dia:attribute name="line_style">
+        <dia:enum val="4"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O7" connection="0"/>
+        <dia:connection handle="1" to="O2" connection="0"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Standard - Line" version="0" id="O10">
+      <dia:attribute name="obj_pos">
+        <dia:point val="22.1887,13.3"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="7.82132,13.2463;22.2424,14.4537"/>
+      </dia:attribute>
+      <dia:attribute name="conn_endpoints">
+        <dia:point val="22.1887,13.3"/>
+        <dia:point val="7.875,14.4"/>
+      </dia:attribute>
+      <dia:attribute name="numcp">
+        <dia:int val="1"/>
+      </dia:attribute>
+      <dia:attribute name="line_color">
+        <dia:color val="#e60505"/>
+      </dia:attribute>
+      <dia:attribute name="line_style">
+        <dia:enum val="4"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O7" connection="7"/>
+        <dia:connection handle="1" to="O2" connection="7"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Standard - Line" version="0" id="O11">
+      <dia:attribute name="obj_pos">
+        <dia:point val="22.1887,9.5417"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="7.82161,9.48831;22.2421,10.6034"/>
+      </dia:attribute>
+      <dia:attribute name="conn_endpoints">
+        <dia:point val="22.1887,9.5417"/>
+        <dia:point val="7.875,10.55"/>
+      </dia:attribute>
+      <dia:attribute name="numcp">
+        <dia:int val="1"/>
+      </dia:attribute>
+      <dia:attribute name="line_color">
+        <dia:color val="#e60505"/>
+      </dia:attribute>
+      <dia:attribute name="line_style">
+        <dia:enum val="4"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O7" connection="2"/>
+        <dia:connection handle="1" to="O2" connection="2"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Geometric - Perfect Circle" version="1" id="O12">
+      <dia:attribute name="obj_pos">
+        <dia:point val="23.23,10.5742"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="23.18,10.5242;24.13,11.4742"/>
+      </dia:attribute>
+      <dia:attribute name="meta">
+        <dia:composite type="dict"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="23.23,10.5742"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="0.84999999999999787"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="0.84999999999999787"/>
+      </dia:attribute>
+      <dia:attribute name="line_width">
+        <dia:real val="0.10000000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="line_colour">
+        <dia:color val="#000000"/>
+      </dia:attribute>
+      <dia:attribute name="fill_colour">
+        <dia:color val="#ffffff"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="line_style">
+        <dia:enum val="0"/>
+        <dia:real val="1"/>
+      </dia:attribute>
+      <dia:attribute name="flip_horizontal">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="flip_vertical">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="subscale">
+        <dia:real val="1"/>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - Line" version="0" id="O13">
+      <dia:attribute name="obj_pos">
+        <dia:point val="24.08,10.9992"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="24.03,10.6388;32.4953,11.3624"/>
+      </dia:attribute>
+      <dia:attribute name="conn_endpoints">
+        <dia:point val="24.08,10.9992"/>
+        <dia:point val="32.3835,11.0007"/>
+      </dia:attribute>
+      <dia:attribute name="numcp">
+        <dia:int val="1"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow">
+        <dia:enum val="22"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_length">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_width">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O12" connection="3"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Standard - Text" version="1" id="O14">
+      <dia:attribute name="obj_pos">
+        <dia:point val="25.3454,10.49"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="25.3454,9.895;29.9904,10.6425"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#pad 1 (source)#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="0.80000000000000004"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="25.3454,10.49"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+      <dia:attribute name="valign">
+        <dia:enum val="3"/>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Geometric - Perfect Circle" version="1" id="O15">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-1.44491,11.6506"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-1.49491,11.6006;-0.54491,12.5506"/>
+      </dia:attribute>
+      <dia:attribute name="meta">
+        <dia:composite type="dict"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="-1.44491,11.6506"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="0.84999999999999787"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="0.84999999999999787"/>
+      </dia:attribute>
+      <dia:attribute name="line_width">
+        <dia:real val="0.10000000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="line_colour">
+        <dia:color val="#000000"/>
+      </dia:attribute>
+      <dia:attribute name="fill_colour">
+        <dia:color val="#ffffff"/>
+      </dia:attribute>
+      <dia:attribute name="show_background">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="line_style">
+        <dia:enum val="0"/>
+        <dia:real val="1"/>
+      </dia:attribute>
+      <dia:attribute name="flip_horizontal">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="flip_vertical">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="subscale">
+        <dia:real val="1"/>
+      </dia:attribute>
+    </dia:object>
+    <dia:object type="Standard - Line" version="0" id="O16">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-9.61991,12.09"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-9.67,11.7149;-1.33311,12.4385"/>
+      </dia:attribute>
+      <dia:attribute name="conn_endpoints">
+        <dia:point val="-9.61991,12.09"/>
+        <dia:point val="-1.44491,12.0756"/>
+      </dia:attribute>
+      <dia:attribute name="numcp">
+        <dia:int val="1"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow">
+        <dia:enum val="22"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_length">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:attribute name="end_arrow_width">
+        <dia:real val="0.5"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="1" to="O15" connection="2"/>
+      </dia:connections>
+    </dia:object>
+    <dia:object type="Standard - Text" version="1" id="O17">
+      <dia:attribute name="obj_pos">
+        <dia:point val="-7.39291,11.49"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-7.39291,10.895;-3.58791,11.6425"/>
+      </dia:attribute>
+      <dia:attribute name="text">
+        <dia:composite type="text">
+          <dia:attribute name="string">
+            <dia:string>#pad 0 (sink)#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="font">
+            <dia:font family="sans" style="0" name="Helvetica"/>
+          </dia:attribute>
+          <dia:attribute name="height">
+            <dia:real val="0.80000000000000004"/>
+          </dia:attribute>
+          <dia:attribute name="pos">
+            <dia:point val="-7.39291,11.49"/>
+          </dia:attribute>
+          <dia:attribute name="color">
+            <dia:color val="#000000"/>
+          </dia:attribute>
+          <dia:attribute name="alignment">
+            <dia:enum val="0"/>
+          </dia:attribute>
+        </dia:composite>
+      </dia:attribute>
+      <dia:attribute name="valign">
+        <dia:enum val="3"/>
+      </dia:attribute>
+    </dia:object>
+  </dia:layer>
+</dia:diagram>
Documentation/DocBook/media/v4l/subdev-image-processing-crop.svg new file +63 -0

63 lines not on this page · raw message

Documentation/DocBook/media/v4l/subdev-image-processing-full.dia new file +1588 -0

1,588 lines not on this page · raw message

Documentation/DocBook/media/v4l/subdev-image-processing-full.svg new file +163 -0

163 lines not on this page · raw message

Documentation/DocBook/media/v4l/subdev-image-processing-scaling-multi-source.dia new file +1152 -0

572 lines not on this page · raw message

Documentation/DocBook/media/v4l/subdev-image-processing-scaling-multi-source.svg new file +116 -0

116 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.

#10 lore raw

PATCH v5 9/35 v4l: Add subdev selections documentation

In reply to Sakari Ailus

Add documentation for V4L2 subdev selection API. This changes also experimental V4L2 subdev API so that scaling now works through selection API only.

---
 Documentation/DocBook/media/Makefile               |    4 +-
 Documentation/DocBook/media/v4l/compat.xml         |    9 +
 Documentation/DocBook/media/v4l/dev-subdev.xml     |  202 +++++++++++++++--
 Documentation/DocBook/media/v4l/v4l2.xml           |   17 ++-
 .../media/v4l/vidioc-subdev-g-selection.xml        |  228 ++++++++++++++++++++
 5 files changed, 433 insertions(+), 27 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml
Documentation/DocBook/media/Makefile +3 -1
index 6628b4b..3625209 100644
@@ -70,6 +70,8 @@ IOCTLS = \
 	VIDIOC_SUBDEV_ENUM_MBUS_CODE \
 	VIDIOC_SUBDEV_ENUM_FRAME_SIZE \
 	VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \
+	VIDIOC_SUBDEV_G_SELECTION \
+	VIDIOC_SUBDEV_S_SELECTION \
 
 TYPES = \
 	$(shell perl -ne 'print "$$1 " if /^typedef\s+[^\s]+\s+([^\s]+)\;/' $(srctree)/include/linux/videodev2.h) \
@@ -193,7 +195,7 @@ DVB_DOCUMENTED = \
 #
 
 install_media_images = \
-	$(Q)cp $(OBJIMGFILES) $(MEDIA_OBJ_DIR)/media_api
+	$(Q)cp $(OBJIMGFILES) $(MEDIA_SRC_DIR)/v4l/*.svg $(MEDIA_OBJ_DIR)/media_api
 
 $(MEDIA_OBJ_DIR)/%: $(MEDIA_SRC_DIR)/%.b64
 	$(Q)base64 -d $< >$@
Documentation/DocBook/media/v4l/compat.xml +9 -0
index 8cd5c96..603fa4ad 100644
@@ -2407,6 +2407,11 @@ details.</para>
 	  <para>Added integer menus, the new type will be
 	  V4L2_CTRL_TYPE_INTEGER_MENU.</para>
         </listitem>
+        <listitem>
+	  <para>Added selection API for V4L2 subdev interface:
+	  &VIDIOC-SUBDEV-G-SELECTION; and
+	  &VIDIOC-SUBDEV-S-SELECTION;.</para>
+        </listitem>
       </orderedlist>
     </section>
 
@@ -2523,6 +2528,10 @@ ioctls.</para>
         <listitem>
 	  <para>Selection API. <xref linkend="selection-api" /></para>
         </listitem>
+        <listitem>
+	  <para>Sub-device selection API: &VIDIOC-SUBDEV-G-SELECTION;
+	  and &VIDIOC-SUBDEV-S-SELECTION; ioctls.</para>
+        </listitem>
       </itemizedlist>
     </section>
 
Documentation/DocBook/media/v4l/dev-subdev.xml +178 -24

226 lines not on this page · raw message

Documentation/DocBook/media/v4l/v4l2.xml +15 -2
index ff11a13..912ec9c 100644
@@ -96,6 +96,17 @@ Remote Controller chapter.</contrib>
 	  </address>
 	</affiliation>
       </author>
+
+      <author>
+	<firstname>Sakari</firstname>
+	<surname>Ailus</surname>
+	<contrib>Subdev selections API.</contrib>
+	<affiliation>
+	  <address>
+	    <email>[email protected]</email>
+	  </address>
+	</affiliation>
+      </author>
     </authorgroup>
 
     <copyright>
@@ -129,9 +140,10 @@ applications. -->
 
       <revision>
 	<revnumber>3.4</revnumber>
-	<date>2012-01-26</date>
+	<date>2012-02-02</date>
 	<authorinitials>sa</authorinitials>
-	<revremark>Added V4L2_CTRL_TYPE_INTEGER_MENU.</revremark>
+	<revremark>Added V4L2_CTRL_TYPE_INTEGER_MENU. Added V4L2 subdev
+		   selections API.</revremark>
       </revision>
       <revision>
 	<revnumber>3.3</revnumber>
@@ -537,6 +549,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 +228 -0

228 lines not on this page · raw message

Signature · 1 line
1.7.2.5
maintainer Acked-by on v5 9/35
#11 lore raw

Re: [PATCH v5 09/35] v4l: Add subdev selections documentation

Hi Sakari,

Thanks for the patch.

Quoted 5 lines · On Tuesday 06 March 2012 18:32:50 Sakari Ailus wrote:

Add documentation for V4L2 subdev selection API. This changes also experimental V4L2 subdev API so that scaling now works through selection API only.

(pending a possible rename of ACTIVE to something else)

Signature · 3 lines
Regards,

Laurent Pinchart
#12 lore raw

Re: [PATCH v5 09/35] v4l: Add subdev selections documentation

In reply to Sakari Ailus

Hi Sakari,

Hopefully it's not too late to make a few minor suggestions.

Quoted 5 lines · Sakari Ailus

Add documentation for V4L2 subdev selection API. This changes also experimental V4L2 subdev API so that scaling now works through selection API only.

[snip]

Quoted 2 lines

+
+<para>On sink pads, cropping is applied relatively to the

s/relatively/relative/

Quoted 5 lines
Documentation/DocBook/media/v4l/dev-subdev.xml +5 -0
+      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>

[snip]

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

Quoted 5 lines

+<para>On source pads, cropping is similar to sink pads, with the

Documentation/DocBook/media/v4l/dev-subdev.xml +4 -0
+      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

s/containted/contained/

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

Quoted 5 lines
Documentation/DocBook/media/v4l/dev-subdev.xml +5 -0
+      operation.</para>
+
+<para>The drivers should always use the closest possible
+      rectangle the user requests on all selection targets, unless
+      specificly told otherwise.

s/specificly/specifically/

Quoted 5 lines

+<constant>V4L2_SUBDEV_SEL_FLAG_SIZE_GE</constant> and +<constant>V4L2_SUBDEV_SEL_FLAG_SIZE_LE</constant> flags may be

Documentation/DocBook/media/v4l/dev-subdev.xml +3 -0
+      used to round the image size either up or down.<xref
+      linkend="v4l2-subdev-selection-flags"></xref></para>
+</section>

[snip]

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

Quoted 3 lines

+<constant>V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG</constant> flag. This

Documentation/DocBook/media/v4l/dev-subdev.xml +2 -0
+      flag causes that no propagation of the changes are allowed in
+      any circumstances. This may also cause the accessed rectangle to

"This flag causes that" sounds ungrammatical. I suggest: "This flag causes no propagation of the changes to be allowed under any circumstances."

[snip]

Michael

MATRIX VISION GmbH, Talstrasse 16, DE-71570 Oppenweiler
Registergericht: Amtsgericht Stuttgart, HRB 271090
Geschaeftsfuehrer: Gerhard Thullner, Werner Armingeon, Uwe Furtner, Erhard Meier

#13 lore raw

Re: [PATCH v5 09/35] v4l: Add subdev selections documentation

Hi Michael,

Thanks for the comments.

Quoted 46 lines · Michael Jones

Hi Sakari,

Hopefully it's not too late to make a few minor suggestions.

Quoted 5 lines · Sakari Ailus

Add documentation for V4L2 subdev selection API. This changes also experimental V4L2 subdev API so that scaling now works through selection API only.

[snip]

Quoted 2 lines

+
+<para>On sink pads, cropping is applied relatively to the

s/relatively/relative/

Quoted 5 lines
Documentation/DocBook/media/v4l/dev-subdev.xml +5 -0
+      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>

[snip]

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

Quoted 5 lines

+<para>On source pads, cropping is similar to sink pads, with the

Documentation/DocBook/media/v4l/dev-subdev.xml +4 -0
+      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

s/containted/contained/

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

Quoted 5 lines
Documentation/DocBook/media/v4l/dev-subdev.xml +5 -0
+      operation.</para>
+
+<para>The drivers should always use the closest possible
+      rectangle the user requests on all selection targets, unless
+      specificly told otherwise.

s/specificly/specifically/

Quoted 5 lines

+<constant>V4L2_SUBDEV_SEL_FLAG_SIZE_GE</constant> and +<constant>V4L2_SUBDEV_SEL_FLAG_SIZE_LE</constant> flags may be

Documentation/DocBook/media/v4l/dev-subdev.xml +3 -0
+      used to round the image size either up or down.<xref
+      linkend="v4l2-subdev-selection-flags"></xref></para>
+</section>

[snip]

Quoted 7 lines

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

Quoted 3 lines

+<constant>V4L2_SUBDEV_SEL_FLAG_KEEP_CONFIG</constant> flag. This

Documentation/DocBook/media/v4l/dev-subdev.xml +2 -0
+      flag causes that no propagation of the changes are allowed in
+      any circumstances. This may also cause the accessed rectangle to

"This flag causes that" sounds ungrammatical. I suggest: "This flag causes no propagation of the changes to be allowed under any circumstances."

Applied all of them.

Cheers,

Signature · 2 lines
Sakari Ailus
e-mail: [email protected]	jabber/XMPP/Gmail: [email protected]
#14 lore raw

Re: [PATCH v5 09/35] v4l: Add subdev selections documentation

In reply to Sakari Ailus

Hi Sakari,

Quoted 5 lines · Sakari Ailus

Add documentation for V4L2 subdev selection API. This changes also experimental V4L2 subdev API so that scaling now works through selection API only.

Quoted 8 lines
---
 Documentation/DocBook/media/Makefile               |    4 +-
 Documentation/DocBook/media/v4l/compat.xml         |    9 +
 Documentation/DocBook/media/v4l/dev-subdev.xml     |  202 +++++++++++++++--
 Documentation/DocBook/media/v4l/v4l2.xml           |   17 ++-
 .../media/v4l/vidioc-subdev-g-selection.xml        |  228 ++++++++++++++++++++
 5 files changed, 433 insertions(+), 27 deletions(-)

cre

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

[snip]

Quoted 183 lines
Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +177 -0
new file mode 100644
index 0000000..9164b85
@@ -0,0 +1,228 @@
+<refentry id="vidioc-subdev-g-selection">
+  <refmeta>
+    <refentrytitle>ioctl VIDIOC_SUBDEV_G_SELECTION, VIDIOC_SUBDEV_S_SELECTION</refentrytitle>
+    &manvol;
+  </refmeta>
+
+  <refnamediv>
+    <refname>VIDIOC_SUBDEV_G_SELECTION</refname>
+    <refname>VIDIOC_SUBDEV_S_SELECTION</refname>
+    <refpurpose>Get or set selection rectangles on a subdev pad</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcprototype>
+	<funcdef>int <function>ioctl</function></funcdef>
+	<paramdef>int <parameter>fd</parameter></paramdef>
+	<paramdef>int <parameter>request</parameter></paramdef>
+	<paramdef>struct v4l2_subdev_selection *<parameter>argp</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1>
+    <title>Arguments</title>
+
+    <variablelist>
+      <varlistentry>
+	<term><parameter>fd</parameter></term>
+	<listitem>
+	  <para>&fd;</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>request</parameter></term>
+	<listitem>
+	  <para>VIDIOC_SUBDEV_G_SELECTION, VIDIOC_SUBDEV_S_SELECTION</para>
+	</listitem>
+      </varlistentry>
+      <varlistentry>
+	<term><parameter>argp</parameter></term>
+	<listitem>
+	  <para></para>
+	</listitem>
+      </varlistentry>
+    </variablelist>
+  </refsect1>
+
+  <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 selection API replaces <link
+    linkend="vidioc-subdev-g-crop">the old subdev crop API</link>. All
+    the function of the crop API, and more, are supported by the
+    selections API.</para>
+
+    <para>See <xref linkend="subdev"></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>
+
+      <para>There are two types of selection targets: active and bounds.
+      The ACTIVE targets are the targets which configure the hardware.
+      The BOUNDS target will return a rectangle that contain all
+      possible ACTIVE rectangles.</para>
+    </section>
+
+    <section>
+      <title>Discovering supported features</title>
+
+      <para>To discover which targets are supported, the user can
+      perform <constant>VIDIOC_SUBDEV_G_SELECTION</constant> on them.
+      Any unsupported target will return
+      <constant>EINVAL</constant>.</para>
+    </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>0x0000</entry>
+	    <entry>Active crop. Defines the cropping
+	    performed by the processing step.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_TGT_CROP_BOUNDS</constant></entry>
+	    <entry>0x0002</entry>
+	    <entry>Bounds of the crop rectangle.</entry>
+	  </row>
+	  <row>
+	    <entry><constant>V4L2_SUBDEV_SEL_TGT_COMPOSE_ACTIVE</constant></entry>
+	    <entry>0x0100</entry>
+	    <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_BOUNDS</constant></entry>
+	    <entry>0x0102</entry>
+	    <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. Albeit the driver may choose a lesser size,
+	    it will only do so due to hardware limitations. Without
+	    this flag (and
+	    <constant>V4L2_SUBDEV_SEL_FLAG_SIZE_LE</constant>) the
+	    behaviour is to choose the closest possible
+	    rectangle.</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. Albeit the driver may choose a greater size, it
+	    will only do so due to hardware limitations.</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>

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

Quoted 10 lines
Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +10 -0
+	  <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>

Shouldn't it be "Selection rectangle, in pixels." ?

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

Quoted 12 lines
Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +12 -0
+	  </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>

--

Regards,
Sylwester

Signature · 3 lines
Sylwester Nawrocki
실베스터 나브로츠키
Samsung Poland R&D Center
#15 lore raw

Re: [PATCH v5 09/35] v4l: Add subdev selections documentation

Hi Sylwester,

Thanks for the comment!

On Thu, Mar 15, 2012 at 10:55:25AM +0100, Sylwester Nawrocki wrote:
...

Quoted 22 lines
Quoted 22 lines
Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +22 -0
+	<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
Quoted 8 lines

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

Quoted 6 lines
Documentation/DocBook/media/v4l/vidioc-subdev-g-selection.xml new file +6 -0
+	    <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>

Shouldn't it be "Selection rectangle, in pixels." ?

Indeed. Fixed and pushed to my git.linuxtv.org tree. Nothing changes in the pull req so I won't send a new one. :-)

Cheers,

Signature · 2 lines
Sakari Ailus
e-mail: [email protected]	jabber/XMPP/Gmail: [email protected]
#16 lore raw

PATCH v5 10/35 v4l: Mark VIDIOC_SUBDEV_G_CROP and VIDIOC_SUBDEV_S_CROP obsolete

In reply to Sakari Ailus

These two IOCTLS are obsoleted by VIDIOC_SUBDEV_G_SELECTION and VIDIOC_SUBDEV_S_SELECTION. Mark them obsolete.

---
 Documentation/DocBook/media/v4l/compat.xml         |    7 +++++++
 .../DocBook/media/v4l/vidioc-subdev-g-crop.xml     |    9 ++++++---
 2 files changed, 13 insertions(+), 3 deletions(-)
Documentation/DocBook/media/v4l/compat.xml +7 -0
index 603fa4ad..ebfe47e 100644
@@ -2547,6 +2547,13 @@ interfaces and should not be implemented in new drivers.</para>
 <constant>VIDIOC_S_MPEGCOMP</constant> ioctls. Use Extended Controls,
 <xref linkend="extended-controls" />.</para>
         </listitem>
+        <listitem>
+	  <para><constant>VIDIOC_SUBDEV_G_CROP</constant> and
+	  <constant>VIDIOC_SUBDEV_S_CROP</constant> ioctls. Use
+	  <constant>VIDIOC_SUBDEV_G_SELECTION</constant> and
+	  <constant>VIDIOC_SUBDEV_S_SELECTION</constant>, <xref
+	  linkend="vidioc-subdev-g-selection" />.</para>
+        </listitem>
       </itemizedlist>
     </section>
   </section>
Documentation/DocBook/media/v4l/vidioc-subdev-g-crop.xml +6 -3
index 0619732..4cddd78 100644
@@ -58,9 +58,12 @@
     <title>Description</title>
 
     <note>
-      <title>Experimental</title>
-      <para>This is an <link linkend="experimental">experimental</link>
-      interface and may change in the future.</para>
+      <title>Obsolete</title>
+
+      <para>This is an <link linkend="obsolete">obsolete</link>
+      interface and may be removed in the future. It is superseded by
+      <link linkend="vidioc-subdev-g-selection">the selection
+      API</link>.</para>
     </note>
 
     <para>To retrieve the current crop rectangle applications set the
Signature · 1 line
1.7.2.5
#17 lore raw

PATCH v5 11/35 v4l: Image source control class

In reply to Sakari Ailus

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       |   86 ++++++++++++++++++++
 .../DocBook/media/v4l/vidioc-g-ext-ctrls.xml       |    6 ++
 drivers/media/video/v4l2-ctrls.c                   |    7 ++
 include/linux/videodev2.h                          |    9 ++
 4 files changed, 108 insertions(+), 0 deletions(-)
Documentation/DocBook/media/v4l/controls.xml +86 -0
index 3f3d2e2..2257db4 100644
@@ -3438,4 +3438,90 @@ 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_VBLANK</constant></entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Vertical blanking. The idle period
+	    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 rate defined by
+	    <constant>V4L2_CID_PIXEL_RATE</constant> control in the
+	    same sub-device.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_HBLANK</constant></entry>
+	    <entry>integer</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Horizontal blanking. The idle
+	    period 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_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 b17a7aa..f420034 100644
@@ -265,6 +265,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 +7 -0
index f0484bd..3ca6bc7 100644
@@ -623,6 +623,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";
 
+	/* Image source controls */
+	case V4L2_CID_IMAGE_SOURCE_CLASS:	return "Image Source Controls";
+	case V4L2_CID_VBLANK:			return "Vertical Blanking";
+	case V4L2_CID_HBLANK:			return "Horizontal Blanking";
+	case V4L2_CID_ANALOGUE_GAIN:		return "Analogue Gain";
+
 	default:
 		return NULL;
 	}
@@ -722,6 +728,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 +9 -0
index e3c6302..ca64202 100644
@@ -1136,6 +1136,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 controls */
 
 #define V4L2_CTRL_ID_MASK      	  (0x0fffffff)
 #define V4L2_CTRL_ID2CLASS(id)    ((id) & 0x0fff0000UL)
@@ -1762,6 +1763,14 @@ 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_VBLANK				(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 1)
+#define V4L2_CID_HBLANK				(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2)
+#define V4L2_CID_ANALOGUE_GAIN			(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3)
+
 /*
  *	T U N I N G
  */
Signature · 1 line
1.7.2.5
#18 lore raw

PATCH v5 12/35 v4l: Image processing control class

In reply to Sakari Ailus

Add control class for image processing controls. The control class deals with controls processing image, for example digital gain or noise filtering, which can be present in any part of the pipeline.

---
 Documentation/DocBook/media/v4l/controls.xml       |   82 ++++++++++++++++++++
 .../DocBook/media/v4l/vidioc-g-ext-ctrls.xml       |    6 ++
 drivers/media/video/v4l2-ctrls.c                   |   13 +++
 include/linux/videodev2.h                          |    8 ++
 4 files changed, 109 insertions(+), 0 deletions(-)
Documentation/DocBook/media/v4l/controls.xml +82 -0
index 2257db4..4ca03f1 100644
@@ -3524,4 +3524,86 @@ interface and may change in the future.</para>
 
     </section>
 
+    <section id="image-process-controls">
+      <title>Image Process 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 processing functions. Unlike
+	<constant>V4L2_CID_IMAGE_SOURCE_CLASS</constant>, the controls in
+	this class affect processing the image, and do not control capturing
+	of it.
+      </para>
+
+      <table pgwide="1" frame="none" id="image-process-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_PROC_CLASS</constant></entry>
+	    <entry>class</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">The IMAGE_PROC class descriptor.</entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_LINK_FREQ</constant></entry>
+	    <entry>integer menu</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Data bus frequency. Together with the
+	    media bus pixel code, bus type (clock cycles per sample), the
+	    data bus frequency defines the pixel rate
+	    (<constant>V4L2_CID_PIXEL_RATE</constant>) in the
+	    pixel array (or possibly elsewhere, if the device is not an
+	    image sensor). The frame rate can be calculated from the pixel
+	    clock, image width and height and horizontal and vertical
+	    blanking. While the pixel rate control may be defined elsewhere
+	    than in the subdev containing the pixel array, the frame rate
+	    cannot be obtained from that information. This is because only
+	    on the pixel array it can be assumed that the vertical and
+	    horizontal blanking information is exact: no other blanking is
+	    allowed in the pixel array. The selection of frame rate is
+	    performed by selecting the desired horizontal and vertical
+	    blanking. The unit of this control is Hz. </entry>
+	  </row>
+	  <row>
+	    <entry spanname="id"><constant>V4L2_CID_PIXEL_RATE</constant></entry>
+	    <entry>64-bit integer</entry>
+	  </row>
+	  <row>
+	    <entry spanname="descr">Pixel rate in the source pads of
+	    the subdev. This control is read-only and its unit is
+	    pixels / second.
+	    </entry>
+	  </row>
+	  <row><entry></entry></row>
+	</tbody>
+      </tgroup>
+      </table>
+
+    </section>
 </section>
Documentation/DocBook/media/v4l/vidioc-g-ext-ctrls.xml +6 -0
index f420034..f41a2f5 100644
@@ -271,6 +271,12 @@ These controls are described in <xref
 	    source controls. These controls are described in <xref
 	    linkend="image-source-controls" />.</entry>
 	  </row>
+	  <row>
+	    <entry><constant>V4L2_CTRL_CLASS_IMAGE_PROC</constant></entry>
+	    <entry>0x9e0000</entry> <entry>The class containing image
+	    processing controls. These controls are described in <xref
+	    linkend="image-process-controls" />.</entry>
+	  </row>
 	</tbody>
       </tgroup>
     </table>
drivers/media/video/v4l2-ctrls.c +13 -0
index 3ca6bc7..1cbf97f 100644
@@ -629,6 +629,11 @@ const char *v4l2_ctrl_get_name(u32 id)
 	case V4L2_CID_HBLANK:			return "Horizontal Blanking";
 	case V4L2_CID_ANALOGUE_GAIN:		return "Analogue Gain";
 
+	/* Image processing controls */
+	case V4L2_CID_IMAGE_PROC_CLASS:		return "Image Processing Controls";
+	case V4L2_CID_LINK_FREQ:		return "Link Frequency";
+	case V4L2_CID_PIXEL_RATE:		return "Pixel Rate";
+
 	default:
 		return NULL;
 	}
@@ -719,6 +724,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_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;
@@ -729,6 +737,7 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 	case V4L2_CID_FM_TX_CLASS:
 	case V4L2_CID_FLASH_CLASS:
 	case V4L2_CID_IMAGE_SOURCE_CLASS:
+	case V4L2_CID_IMAGE_PROC_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;
@@ -754,6 +763,10 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
 		*type = V4L2_CTRL_TYPE_INTEGER64;
 		*flags |= V4L2_CTRL_FLAG_READ_ONLY | V4L2_CTRL_FLAG_VOLATILE;
 		break;
+	case V4L2_CID_PIXEL_RATE:
+		*type = V4L2_CTRL_TYPE_INTEGER64;
+		*flags |= V4L2_CTRL_FLAG_READ_ONLY;
+		break;
 	default:
 		*type = V4L2_CTRL_TYPE_INTEGER;
 		break;
include/linux/videodev2.h +8 -0
index ca64202..f46350e 100644
@@ -1137,6 +1137,7 @@ struct v4l2_ext_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 controls */
+#define V4L2_CTRL_CLASS_IMAGE_PROC 0x009e0000	/* Image processing controls */
 
 #define V4L2_CTRL_ID_MASK      	  (0x0fffffff)
 #define V4L2_CTRL_ID2CLASS(id)    ((id) & 0x0fff0000UL)
@@ -1771,6 +1772,13 @@ enum v4l2_flash_strobe_source {
 #define V4L2_CID_HBLANK				(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 2)
 #define V4L2_CID_ANALOGUE_GAIN			(V4L2_CID_IMAGE_SOURCE_CLASS_BASE + 3)
 
+/* Image processing controls */
+#define V4L2_CID_IMAGE_PROC_CLASS_BASE		(V4L2_CTRL_CLASS_IMAGE_PROC | 0x900)
+#define V4L2_CID_IMAGE_PROC_CLASS		(V4L2_CTRL_CLASS_IMAGE_PROC | 1)
+
+#define V4L2_CID_LINK_FREQ			(V4L2_CID_IMAGE_PROC_CLASS_BASE + 1)
+#define V4L2_CID_PIXEL_RATE			(V4L2_CID_IMAGE_PROC_CLASS_BASE + 2)
+
 /*
  *	T U N I N G
  */
Signature · 1 line
1.7.2.5
#19 lore raw

PATCH v5 13/35 v4l: Document raw bayer 4CC codes

In reply to Sakari Ailus

Document guidelines how 4CC codes should be named. Only raw bayer is included currently. Other formats should be documented later on.

---
 Documentation/video4linux/4CCs.txt |   32 ++++++++++++++++++++++++++++++++
 1 files changed, 32 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/video4linux/4CCs.txt
Documentation/video4linux/4CCs.txt new file +32 -0
new file mode 100644
index 0000000..41241af
@@ -0,0 +1,32 @@
+Guidelines for Linux4Linux pixel format 4CCs
+============================================
+
+Guidelines for Video4Linux 4CC codes defined using v4l2_fourcc() are
+specified in this document. First of the characters defines the nature of
+the pixel format, compression and colour space. The interpretation of the
+other three characters depends on the first one.
+
+Existing 4CCs may not obey these guidelines.
+
+Formats
+=======
+
+Raw bayer
+---------
+
+The following first characters are used by raw bayer formats:
+
+	B: raw bayer, uncompressed
+	b: raw bayer, DPCM compressed
+	a: A-law compressed
+	u: u-law compressed
+
+2nd character: pixel order
+	B: BGGR
+	G: GBRG
+	g: GRBG
+	R: RGGB
+
+3rd character: uncompressed bits-per-pixel 0--9, A--
+
+4th character: compressed bits-per-pixel 0--9, A--
Signature · 1 line
1.7.2.5
#20 lore raw

PATCH v5 14/35 v4l: Add DPCM compressed raw bayer pixel formats

In reply to Sakari Ailus

Add three other colour orders for 10-bit to 8-bit DPCM compressed raw bayer pixel formats.

---
 Documentation/DocBook/media/v4l/pixfmt-srggb10.xml |    2 +-
 .../DocBook/media/v4l/pixfmt-srggb10dpcm8.xml      |   29 ++++++++++++++++++++
 Documentation/DocBook/media/v4l/pixfmt.xml         |    1 +
 include/linux/videodev2.h                          |    3 ++
 4 files changed, 34 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml
Documentation/DocBook/media/v4l/pixfmt-srggb10.xml +1 -1
index 7b27409..c1c62a9 100644
@@ -1,4 +1,4 @@
-    <refentry>
+    <refentry id="pixfmt-srggb10">
       <refmeta>
 	<refentrytitle>V4L2_PIX_FMT_SRGGB10 ('RG10'),
 	 V4L2_PIX_FMT_SGRBG10 ('BA10'),
Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml new file +29 -0
new file mode 100644
index 0000000..80937f1
@@ -0,0 +1,29 @@
+    <refentry>
+      <refmeta>
+	<refentrytitle>
+	 V4L2_PIX_FMT_SRGGB10DPCM8 ('bBA8'),
+	 V4L2_PIX_FMT_SGBRG10DPCM8 ('bGA8'),
+	 V4L2_PIX_FMT_SGRBG10DPCM8 ('BD10'),
+	 V4L2_PIX_FMT_SBGGR10DPCM8 ('bRA8'),
+	 </refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname id="V4L2-PIX-FMT-SRGGB10DPCM8"><constant>V4L2_PIX_FMT_SRGGB10DPCM8</constant></refname>
+	<refname id="V4L2-PIX-FMT-SGBRG10DPCM8"><constant>V4L2_PIX_FMT_SGBRG10DPCM8</constant></refname>
+	<refname id="V4L2-PIX-FMT-SGRBG10DPCM8"><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></refname>
+	<refname id="V4L2-PIX-FMT-SBGGR10DPCM8"><constant>V4L2_PIX_FMT_SBGGR10DPCM8</constant></refname>
+	<refpurpose>10-bit Bayer formats compressed to 8 bits</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>The following four pixel formats are raw sRGB / Bayer formats
+	with 10 bits per colour compressed to 8 bits each, using DPCM
+	compression. DPCM, differential pulse-code modulation, is lossy.
+	Each colour component consumes 8 bits of memory. In other respects
+	this format is similar to <xref
+	linkend="pixfmt-srggb10">.</xref></para>
+
+      </refsect1>
+    </refentry>
Documentation/DocBook/media/v4l/pixfmt.xml +1 -0
index 31eaae2..74d4fcd 100644
@@ -673,6 +673,7 @@ access the palette, this must be done with ioctls of the Linux framebuffer API.<
     &sub-srggb8;
     &sub-sbggr16;
     &sub-srggb10;
+    &sub-srggb10dpcm8;
     &sub-srggb12;
   </section>
 
include/linux/videodev2.h +3 -0
index f46350e..76f3153 100644
@@ -378,7 +378,10 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12  GRGR.. BGBG.. */
 #define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12  RGRG.. GBGB.. */
 	/* 10bit raw bayer DPCM compressed to 8 bits */
+#define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8')
+#define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8')
 #define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0')
+#define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8')
 	/*
 	 * 10bit raw bayer, expanded to 16 bits
 	 * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb...
Signature · 1 line
1.7.2.5
#21 lore raw

Re: [PATCH v5 14/35] v4l: Add DPCM compressed raw bayer pixel formats

Sakari,

Quoted 34 lines · Sakari Ailus

Add three other colour orders for 10-bit to 8-bit DPCM compressed raw bayer
pixel formats.

---
 Documentation/DocBook/media/v4l/pixfmt-srggb10.xml |    2 +- .../DocBook/media/v4l/pixfmt-srggb10dpcm8.xml      |   29
++++++++++++++++++++
 Documentation/DocBook/media/v4l/pixfmt.xml         |    1 + include/linux/videodev2.h                          |    3 ++

 4 files changed, 34 insertions(+), 1 deletions(-)

 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml

Documentation/DocBook/media/v4l/pixfmt-srggb10.xml +1 -1
index 7b27409..c1c62a9 100644
@@ -1,4 +1,4 @@
-    <refentry>
+    <refentry id="pixfmt-srggb10">

      <refmeta> <refentrytitle>V4L2_PIX_FMT_SRGGB10 ('RG10'), V4L2_PIX_FMT_SGRBG10 ('BA10'),

Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml new file +0 -0
new file mode 100644
index 0000000..80937f1

Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml line 8

Quoted 8 lines
Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml new file +8 -0
@@ -0,0 +1,29 @@
+    <refentry>
+      <refmeta>
+       <refentrytitle>
+        V4L2_PIX_FMT_SRGGB10DPCM8 ('bBA8'),
+        V4L2_PIX_FMT_SGBRG10DPCM8 ('bGA8'),
+        V4L2_PIX_FMT_SGRBG10DPCM8 ('BD10'),
+        V4L2_PIX_FMT_SBGGR10DPCM8 ('bRA8'),
+        </refentrytitle>

You missed here to change as per the 4CC code documentation.

Regards,
--Prabhakar Lad

Quoted 64 lines
Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml new file +4 -0
+       &manvol;
+      </refmeta>
+      <refnamediv>
+       <refname

id="V4L2-PIX-FMT-SRGGB10DPCM8"><constant>V4L2_PIX_FMT_SRGGB10DPCM8</constant></refname>
+       <refname id="V4L2-PIX-FMT-SGBRG10DPCM8"><constant>V4L2_PIX_FMT_SGBRG10DPCM8</constant></refname>
+       <refname id="V4L2-PIX-FMT-SGRBG10DPCM8"><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></refname>
+       <refname id="V4L2-PIX-FMT-SBGGR10DPCM8"><constant>V4L2_PIX_FMT_SBGGR10DPCM8</constant></refname>
+       <refpurpose>10-bit Bayer formats compressed to 8 bits</refpurpose>
+      </refnamediv>
+      <refsect1>
+       <title>Description</title>
+
+       <para>The following four pixel formats are raw sRGB / Bayer formats
+       with 10 bits per colour compressed to 8 bits each, using DPCM
+       compression. DPCM, differential pulse-code modulation, is lossy.
+       Each colour component consumes 8 bits of memory. In other respects
+       this format is similar to <xref
+       linkend="pixfmt-srggb10">.</xref></para>

Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml new file +3 -0
+
+      </refsect1>
+    </refentry>
Documentation/DocBook/media/v4l/pixfmt.xml +0 -0
index 31eaae2..74d4fcd 100644
@@ -673,6 +673,7 @@ access the palette, this must be done with ioctls of

the Linux framebuffer API.<
    &sub-srggb8;
    &sub-sbggr16;
    &sub-srggb10;
+    &sub-srggb10dpcm8;
    &sub-srggb12;
  </section>

include/linux/videodev2.h +0 -0
index f46350e..76f3153 100644
@@ -378,7 +378,10 @@ struct v4l2_pix_format {
  #define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12

 GRGR.. BGBG.. */
 #define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */
       /* 10bit raw bayer DPCM compressed to 8 bits */

include/linux/videodev2.h +2 -0
+#define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8')
+#define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8')

 #define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') +#define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8') /*
        * 10bit raw bayer, expanded to 16 bits
        * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... --
1.7.2.5

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

#22 lore raw

Re: [PATCH v5 14/35] v4l: Add DPCM compressed raw bayer pixel formats

Hi Prabhakar,

Quoted 1 line · Prabhakar Lad

On Tue, Mar 6, 2012 at 10:02 PM, Sakari Ailus<[email protected]> wrote:

...

Quoted 9 lines
Quoted 9 lines
Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml new file +2 -0
new file mode 100644
index 0000000..80937f1
@@ -0,0 +1,29 @@
+<refentry>
+<refmeta>
Quoted 8 lines

Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml line 8

Quoted 6 lines
Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml new file +6 -0
+<refentrytitle>
+        V4L2_PIX_FMT_SRGGB10DPCM8 ('bBA8'),
+        V4L2_PIX_FMT_SGBRG10DPCM8 ('bGA8'),
+        V4L2_PIX_FMT_SGRBG10DPCM8 ('BD10'),
+        V4L2_PIX_FMT_SBGGR10DPCM8 ('bRA8'),
+</refentrytitle>

You missed here to change as per the 4CC code documentation.

Thanks!

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

PATCH 14/40 v4l: Add DPCM compressed raw bayer pixel formats

In reply to Prabhakar Lad

Add three other colour orders for 10-bit to 8-bit DPCM compressed raw bayer pixel formats.

---
 Documentation/DocBook/media/v4l/pixfmt-srggb10.xml |    2 +-
 .../DocBook/media/v4l/pixfmt-srggb10dpcm8.xml      |   29 ++++++++++++++++++++
 Documentation/DocBook/media/v4l/pixfmt.xml         |    1 +
 include/linux/videodev2.h                          |    3 ++
 4 files changed, 34 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml
Documentation/DocBook/media/v4l/pixfmt-srggb10.xml +1 -1
index 7b27409..c1c62a9 100644
@@ -1,4 +1,4 @@
-    <refentry>
+    <refentry id="pixfmt-srggb10">
       <refmeta>
 	<refentrytitle>V4L2_PIX_FMT_SRGGB10 ('RG10'),
 	 V4L2_PIX_FMT_SGRBG10 ('BA10'),
Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml new file +29 -0
new file mode 100644
index 0000000..5b2b03c
@@ -0,0 +1,29 @@
+    <refentry>
+      <refmeta>
+	<refentrytitle>
+	 V4L2_PIX_FMT_SBGGR10DPCM8 ('bBA8'),
+	 V4L2_PIX_FMT_SGBRG10DPCM8 ('bGA8'),
+	 V4L2_PIX_FMT_SGRBG10DPCM8 ('BD10'),
+	 V4L2_PIX_FMT_SRGGB10DPCM8 ('bRA8'),
+	 </refentrytitle>
+	&manvol;
+      </refmeta>
+      <refnamediv>
+	<refname id="V4L2-PIX-FMT-SBGGR10DPCM8"><constant>V4L2_PIX_FMT_SBGGR10DPCM8</constant></refname>
+	<refname id="V4L2-PIX-FMT-SGBRG10DPCM8"><constant>V4L2_PIX_FMT_SGBRG10DPCM8</constant></refname>
+	<refname id="V4L2-PIX-FMT-SGRBG10DPCM8"><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></refname>
+	<refname id="V4L2-PIX-FMT-SRGGB10DPCM8"><constant>V4L2_PIX_FMT_SRGGB10DPCM8</constant></refname>
+	<refpurpose>10-bit Bayer formats compressed to 8 bits</refpurpose>
+      </refnamediv>
+      <refsect1>
+	<title>Description</title>
+
+	<para>The following four pixel formats are raw sRGB / Bayer formats
+	with 10 bits per colour compressed to 8 bits each, using DPCM
+	compression. DPCM, differential pulse-code modulation, is lossy.
+	Each colour component consumes 8 bits of memory. In other respects
+	this format is similar to <xref
+	linkend="pixfmt-srggb10">.</xref></para>
+
+      </refsect1>
+    </refentry>
Documentation/DocBook/media/v4l/pixfmt.xml +1 -0
index 31eaae2..74d4fcd 100644
@@ -673,6 +673,7 @@ access the palette, this must be done with ioctls of the Linux framebuffer API.<
     &sub-srggb8;
     &sub-sbggr16;
     &sub-srggb10;
+    &sub-srggb10dpcm8;
     &sub-srggb12;
   </section>
 
include/linux/videodev2.h +3 -0
index 0805259..dbc0d77 100644
@@ -378,7 +378,10 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12  GRGR.. BGBG.. */
 #define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12  RGRG.. GBGB.. */
 	/* 10bit raw bayer DPCM compressed to 8 bits */
+#define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8')
+#define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8')
 #define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0')
+#define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8')
 	/*
 	 * 10bit raw bayer, expanded to 16 bits
 	 * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb...
Signature · 1 line
1.7.2.5
Acked-by on v1 14/40
#24 lore raw

Re: [PATCH v5.5 14/40] v4l: Add DPCM compressed raw bayer pixel formats

Quoted 6 lines · Sakari Ailus

Add three other colour orders for 10-bit to 8-bit DPCM compressed raw bayer
pixel formats.

Quoted 96 lines

---
 Documentation/DocBook/media/v4l/pixfmt-srggb10.xml |    2 +- .../DocBook/media/v4l/pixfmt-srggb10dpcm8.xml      |   29
++++++++++++++++++++
 Documentation/DocBook/media/v4l/pixfmt.xml         |    1 + include/linux/videodev2.h                          |    3 ++

 4 files changed, 34 insertions(+), 1 deletions(-)

 create mode 100644 Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml

Documentation/DocBook/media/v4l/pixfmt-srggb10.xml +1 -1
index 7b27409..c1c62a9 100644
@@ -1,4 +1,4 @@
-    <refentry>
+    <refentry id="pixfmt-srggb10">

      <refmeta> <refentrytitle>V4L2_PIX_FMT_SRGGB10 ('RG10'), V4L2_PIX_FMT_SGRBG10 ('BA10'),

Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml new file +12 -0
new file mode 100644
index 0000000..5b2b03c
@@ -0,0 +1,29 @@
+    <refentry>
+      <refmeta>
+       <refentrytitle>
+        V4L2_PIX_FMT_SBGGR10DPCM8 ('bBA8'),
+        V4L2_PIX_FMT_SGBRG10DPCM8 ('bGA8'),
+        V4L2_PIX_FMT_SGRBG10DPCM8 ('BD10'),
+        V4L2_PIX_FMT_SRGGB10DPCM8 ('bRA8'),
+        </refentrytitle>
+       &manvol;
+      </refmeta>
+      <refnamediv>
+       <refname

id="V4L2-PIX-FMT-SBGGR10DPCM8"><constant>V4L2_PIX_FMT_SBGGR10DPCM8</constant></refname>
+       <refname id="V4L2-PIX-FMT-SGBRG10DPCM8"><constant>V4L2_PIX_FMT_SGBRG10DPCM8</constant></refname>
+       <refname id="V4L2-PIX-FMT-SGRBG10DPCM8"><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></refname>
+       <refname id="V4L2-PIX-FMT-SRGGB10DPCM8"><constant>V4L2_PIX_FMT_SRGGB10DPCM8</constant></refname>
+       <refpurpose>10-bit Bayer formats compressed to 8 bits</refpurpose>
+      </refnamediv>
+      <refsect1>
+       <title>Description</title>
+
+       <para>The following four pixel formats are raw sRGB / Bayer formats
+       with 10 bits per colour compressed to 8 bits each, using DPCM
+       compression. DPCM, differential pulse-code modulation, is lossy.
+       Each colour component consumes 8 bits of memory. In other respects
+       this format is similar to <xref
+       linkend="pixfmt-srggb10">.</xref></para>

Documentation/DocBook/media/v4l/pixfmt-srggb10dpcm8.xml new file +3 -0
+
+      </refsect1>
+    </refentry>
Documentation/DocBook/media/v4l/pixfmt.xml +0 -0
index 31eaae2..74d4fcd 100644
@@ -673,6 +673,7 @@ access the palette, this must be done with ioctls of

the Linux framebuffer API.<
    &sub-srggb8;
    &sub-sbggr16;
    &sub-srggb10;
+    &sub-srggb10dpcm8;
    &sub-srggb12;
  </section>

include/linux/videodev2.h +0 -0
index 0805259..dbc0d77 100644
@@ -378,7 +378,10 @@ struct v4l2_pix_format {
  #define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12

 GRGR.. BGBG.. */
 #define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */
       /* 10bit raw bayer DPCM compressed to 8 bits */

include/linux/videodev2.h +2 -0
+#define V4L2_PIX_FMT_SBGGR10DPCM8 v4l2_fourcc('b', 'B', 'A', '8')
+#define V4L2_PIX_FMT_SGBRG10DPCM8 v4l2_fourcc('b', 'G', 'A', '8')

 #define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') +#define V4L2_PIX_FMT_SRGGB10DPCM8 v4l2_fourcc('b', 'R', 'A', '8') /*
        * 10bit raw bayer, expanded to 16 bits
        * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb... --
1.7.2.5

#25 lore raw

PATCH v5 15/35 media: Add link_validate() op to check links to the sink pad

In reply to Sakari Ailus

The purpose of the link_validate() op is to allow an entity driver to ensure that the properties of the pads at the both ends of the link are suitable for starting the pipeline. link_validate is called on sink pads on active links which belong to the active part of the graph.

---
 Documentation/media-framework.txt |   19 ++++++++++++++
 drivers/media/media-entity.c      |   50 +++++++++++++++++++++++++++++++++++-
 include/media/media-entity.h      |    5 ++-
 3 files changed, 70 insertions(+), 4 deletions(-)
Documentation/media-framework.txt +19 -0
index 3a0f879..8028754 100644
@@ -335,6 +335,9 @@ the media_entity pipe field.
 Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must
 be identical for all nested calls to the function.
 
+media_entity_pipeline_start() may return an error. In that case, it will
+clean up any the changes it did by itself.
+
 When stopping the stream, drivers must notify the entities with
 
 	media_entity_pipeline_stop(struct media_entity *entity);
@@ -351,3 +354,19 @@ If other operations need to be disallowed on streaming entities (such as
 changing entities configuration parameters) drivers can explicitly check the
 media_entity stream_count field to find out if an entity is streaming. This
 operation must be done with the media_device graph_mutex held.
+
+
+Link validation
+---------------
+
+Link validation is performed by media_entity_pipeline_start() for any
+entity which has sink pads in the pipeline. The
+media_entity::link_validate() callback is used for that purpose. In
+link_validate() callback, entity driver should check that the properties of
+the source pad of the connected entity and its own sink pad match. It is up
+to the type of the entity (and in the end, the properties of the hardware)
+what matching actually means.
+
+Subsystems should facilitate link validation by providing subsystem specific
+helper functions to provide easy access for commonly needed information, and
+in the end provide a way to use driver-specific callbacks.
drivers/media/media-entity.c +48 -2

71 lines not on this page · raw message

include/media/media-entity.h +3 -2
index 29e7bba..0c16f51 100644
@@ -46,6 +46,7 @@ struct media_entity_operations {
 	int (*link_setup)(struct media_entity *entity,
 			  const struct media_pad *local,
 			  const struct media_pad *remote, u32 flags);
+	int (*link_validate)(struct media_link *link);
 };
 
 struct media_entity {
@@ -140,8 +141,8 @@ void media_entity_graph_walk_start(struct media_entity_graph *graph,
 		struct media_entity *entity);
 struct media_entity *
 media_entity_graph_walk_next(struct media_entity_graph *graph);
-void media_entity_pipeline_start(struct media_entity *entity,
-		struct media_pipeline *pipe);
+__must_check int media_entity_pipeline_start(struct media_entity *entity,
+					     struct media_pipeline *pipe);
 void media_entity_pipeline_stop(struct media_entity *entity);
 
 #define media_entity_call(entity, operation, args...)			\
Signature · 1 line
1.7.2.5
#26 lore raw

PATCH v5 16/35 v4l: Improve sub-device documentation for pad ops

In reply to Sakari Ailus

Document that format related configuration is done through pad ops in case the driver does use the media framework.

---
 Documentation/video4linux/v4l2-framework.txt |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)
Documentation/video4linux/v4l2-framework.txt +9 -0
index 659b2ba..f06c563 100644
@@ -262,11 +262,16 @@ struct v4l2_subdev_video_ops {
 	...
 };
 
+struct v4l2_subdev_pad_ops {
+	...
+};
+
 struct v4l2_subdev_ops {
 	const struct v4l2_subdev_core_ops  *core;
 	const struct v4l2_subdev_tuner_ops *tuner;
 	const struct v4l2_subdev_audio_ops *audio;
 	const struct v4l2_subdev_video_ops *video;
+	const struct v4l2_subdev_pad_ops *video;
 };
 
 The core ops are common to all subdevs, the other categories are implemented
@@ -303,6 +308,10 @@ Don't forget to cleanup the media entity before the sub-device is destroyed:
 
 	media_entity_cleanup(&sd->entity);
 
+If the subdev driver intends to process video and integrate with the media
+framework, it must implement format related functionality using
+v4l2_subdev_pad_ops instead of v4l2_subdev_video_ops.
+
 A device (bridge) driver needs to register the v4l2_subdev with the
 v4l2_device:
 
Signature · 1 line
1.7.2.5
#27 lore raw

PATCH v5 17/35 v4l: Implement v4l2_subdev_link_validate()

In reply to Sakari Ailus

v4l2_subdev_link_validate() is the default op for validating a link. In V4L2 subdev context, it is used to call a pad op which performs the proper link check without much extra work.

---
 Documentation/video4linux/v4l2-framework.txt |   12 +++++
 drivers/media/video/v4l2-subdev.c            |   64 ++++++++++++++++++++++++++
 include/media/v4l2-subdev.h                  |   12 +++++
 3 files changed, 88 insertions(+), 0 deletions(-)
Documentation/video4linux/v4l2-framework.txt +12 -0
index f06c563..9d341bc 100644
@@ -312,6 +312,18 @@ If the subdev driver intends to process video and integrate with the media
 framework, it must implement format related functionality using
 v4l2_subdev_pad_ops instead of v4l2_subdev_video_ops.
 
+In that case, the subdev driver may set the link_validate field to provide
+its own link validation function. The link validation function is called for
+every link in the pipeline where both of the ends of the links are V4L2
+sub-devices. The driver is still responsible for validating the correctness
+of the format configuration between sub-devices and video nodes.
+
+If link_validate op is not set, the default function
+v4l2_subdev_link_validate_default() is used instead. This function ensures
+that width, height and the media bus pixel code are equal on both source and
+sink of the link. Subdev drivers are also free to use this function to
+perform the checks mentioned above in addition to their own checks.
+
 A device (bridge) driver needs to register the v4l2_subdev with the
 v4l2_device:
 
drivers/media/video/v4l2-subdev.c +64 -0

70 lines not on this page · raw message

include/media/v4l2-subdev.h +12 -0
index 7e85035..1c2318b 100644
@@ -470,6 +470,11 @@ 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);
+#ifdef CONFIG_MEDIA_CONTROLLER
+	int (*link_validate)(struct v4l2_subdev *sd, struct media_link *link,
+			     struct v4l2_subdev_format *source_fmt,
+			     struct v4l2_subdev_format *sink_fmt);
+#endif /* CONFIG_MEDIA_CONTROLLER */
 };
 
 struct v4l2_subdev_ops {
@@ -602,6 +607,13 @@ static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd)
 	return sd->host_priv;
 }
 
+#ifdef CONFIG_MEDIA_CONTROLLER
+int v4l2_subdev_link_validate_default(struct v4l2_subdev *sd,
+				      struct media_link *link,
+				      struct v4l2_subdev_format *source_fmt,
+				      struct v4l2_subdev_format *sink_fmt);
+int v4l2_subdev_link_validate(struct media_link *link);
+#endif /* CONFIG_MEDIA_CONTROLLER */
 void v4l2_subdev_init(struct v4l2_subdev *sd,
 		      const struct v4l2_subdev_ops *ops);
 
Signature · 1 line
1.7.2.5
#28 lore raw

PATCH v5 18/35 v4l: Allow changing control handler lock

In reply to Sakari Ailus

Allow choosing the lock used by the control handler. This may be handy sometimes when a driver providing multiple subdevs does not want to use several locks to serialise its functions.

---
 drivers/media/video/adp1653.c    |    8 +++---
 drivers/media/video/v4l2-ctrls.c |   39 +++++++++++++++++++------------------
 drivers/media/video/vivi.c       |    4 +-
 include/media/v4l2-ctrls.h       |    9 +++++--
 4 files changed, 32 insertions(+), 28 deletions(-)
drivers/media/video/adp1653.c +4 -4
index 12eedf4..becaba4 100644
@@ -283,19 +283,19 @@ adp1653_init_device(struct adp1653_flash *flash)
 		return -EIO;
 	}
 
-	mutex_lock(&flash->ctrls.lock);
+	mutex_lock(flash->ctrls.lock);
 	/* Reset faults before reading new ones. */
 	flash->fault = 0;
 	rval = adp1653_get_fault(flash);
-	mutex_unlock(&flash->ctrls.lock);
+	mutex_unlock(flash->ctrls.lock);
 	if (rval > 0) {
 		dev_err(&client->dev, "faults detected: 0x%1.1x\n", rval);
 		return -EIO;
 	}
 
-	mutex_lock(&flash->ctrls.lock);
+	mutex_lock(flash->ctrls.lock);
 	rval = adp1653_update_hw(flash);
-	mutex_unlock(&flash->ctrls.lock);
+	mutex_unlock(flash->ctrls.lock);
 	if (rval) {
 		dev_err(&client->dev,
 			"adp1653_update_hw failed at %s\n", __func__);
drivers/media/video/v4l2-ctrls.c +20 -19
index 1cbf97f..c38055f 100644
@@ -1153,7 +1153,8 @@ static inline int handler_set_err(struct v4l2_ctrl_handler *hdl, int err)
 int v4l2_ctrl_handler_init(struct v4l2_ctrl_handler *hdl,
 			   unsigned nr_of_controls_hint)
 {
-	mutex_init(&hdl->lock);
+	hdl->lock = &hdl->_lock;
+	mutex_init(hdl->lock);
 	INIT_LIST_HEAD(&hdl->ctrls);
 	INIT_LIST_HEAD(&hdl->ctrl_refs);
 	hdl->nr_of_buckets = 1 + nr_of_controls_hint / 8;
@@ -1174,7 +1175,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
 	if (hdl == NULL || hdl->buckets == NULL)
 		return;
 
-	mutex_lock(&hdl->lock);
+	mutex_lock(hdl->lock);
 	/* Free all nodes */
 	list_for_each_entry_safe(ref, next_ref, &hdl->ctrl_refs, node) {
 		list_del(&ref->node);
@@ -1191,7 +1192,7 @@ void v4l2_ctrl_handler_free(struct v4l2_ctrl_handler *hdl)
 	hdl->buckets = NULL;
 	hdl->cached = NULL;
 	hdl->error = 0;
-	mutex_unlock(&hdl->lock);
+	mutex_unlock(hdl->lock);
 }
 EXPORT_SYMBOL(v4l2_ctrl_handler_free);
 
@@ -1256,9 +1257,9 @@ static struct v4l2_ctrl_ref *find_ref_lock(
 	struct v4l2_ctrl_ref *ref = NULL;
 
 	if (hdl) {
-		mutex_lock(&hdl->lock);
+		mutex_lock(hdl->lock);
 		ref = find_ref(hdl, id);
-		mutex_unlock(&hdl->lock);
+		mutex_unlock(hdl->lock);
 	}
 	return ref;
 }
@@ -1305,7 +1306,7 @@ static int handler_new_ref(struct v4l2_ctrl_handler *hdl,
 
 	INIT_LIST_HEAD(&new_ref->node);
 
-	mutex_lock(&hdl->lock);
+	mutex_lock(hdl->lock);
 
 	/* Add immediately at the end of the list if the list is empty, or if
 	   the last element in the list has a lower ID.
@@ -1335,7 +1336,7 @@ insert_in_hash:
 	hdl->buckets[bucket] = new_ref;
 
 unlock:
-	mutex_unlock(&hdl->lock);
+	mutex_unlock(hdl->lock);
 	return 0;
 }
 
@@ -1421,9 +1422,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
 		kfree(ctrl);
 		return NULL;
 	}
-	mutex_lock(&hdl->lock);
+	mutex_lock(hdl->lock);
 	list_add_tail(&ctrl->node, &hdl->ctrls);
-	mutex_unlock(&hdl->lock);
+	mutex_unlock(hdl->lock);
 	return ctrl;
 }
 
@@ -1540,7 +1541,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
 		return 0;
 	if (hdl->error)
 		return hdl->error;
-	mutex_lock(&add->lock);
+	mutex_lock(add->lock);
 	list_for_each_entry(ctrl, &add->ctrls, node) {
 		/* Skip handler-private controls. */
 		if (ctrl->is_private)
@@ -1552,7 +1553,7 @@ int v4l2_ctrl_add_handler(struct v4l2_ctrl_handler *hdl,
 		if (ret)
 			break;
 	}
-	mutex_unlock(&add->lock);
+	mutex_unlock(add->lock);
 	return ret;
 }
 EXPORT_SYMBOL(v4l2_ctrl_add_handler);
@@ -1716,11 +1717,11 @@ void v4l2_ctrl_handler_log_status(struct v4l2_ctrl_handler *hdl,
 	len = strlen(prefix);
 	if (len && prefix[len - 1] != ' ')
 		colon = ": ";
-	mutex_lock(&hdl->lock);
+	mutex_lock(hdl->lock);
 	list_for_each_entry(ctrl, &hdl->ctrls, node)
 		if (!(ctrl->flags & V4L2_CTRL_FLAG_DISABLED))
 			log_ctrl(ctrl, prefix, colon);
-	mutex_unlock(&hdl->lock);
+	mutex_unlock(hdl->lock);
 }
 EXPORT_SYMBOL(v4l2_ctrl_handler_log_status);
 
@@ -1732,7 +1733,7 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
 
 	if (hdl == NULL)
 		return 0;
-	mutex_lock(&hdl->lock);
+	mutex_lock(hdl->lock);
 	list_for_each_entry(ctrl, &hdl->ctrls, node)
 		ctrl->done = false;
 
@@ -1757,7 +1758,7 @@ int v4l2_ctrl_handler_setup(struct v4l2_ctrl_handler *hdl)
 		if (ret)
 			break;
 	}
-	mutex_unlock(&hdl->lock);
+	mutex_unlock(hdl->lock);
 	return ret;
 }
 EXPORT_SYMBOL(v4l2_ctrl_handler_setup);
@@ -1772,7 +1773,7 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
 	if (hdl == NULL)
 		return -EINVAL;
 
-	mutex_lock(&hdl->lock);
+	mutex_lock(hdl->lock);
 
 	/* Try to find it */
 	ref = find_ref(hdl, id);
@@ -1797,7 +1798,7 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc)
 					break;
 		}
 	}
-	mutex_unlock(&hdl->lock);
+	mutex_unlock(hdl->lock);
 	if (!ref)
 		return -EINVAL;
 
@@ -1974,7 +1975,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
 	   belong to the same cluster. */
 
 	/* This has to be done with the handler lock taken. */
-	mutex_lock(&hdl->lock);
+	mutex_lock(hdl->lock);
 
 	/* First zero the helper field in the master control references */
 	for (i = 0; i < cs->count; i++)
@@ -1996,7 +1997,7 @@ static int prepare_ext_ctrls(struct v4l2_ctrl_handler *hdl,
 		/* Point the mref helper to the current helper struct. */
 		mref->helper = h;
 	}
-	mutex_unlock(&hdl->lock);
+	mutex_unlock(hdl->lock);
 	return 0;
 }
 
drivers/media/video/vivi.c +2 -2
index d75a1e4..256e9ba 100644
@@ -485,7 +485,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
 	gen_text(dev, vbuf, line++ * 16, 16, str);
 
 	gain = v4l2_ctrl_g_ctrl(dev->gain);
-	mutex_lock(&dev->ctrl_handler.lock);
+	mutex_lock(dev->ctrl_handler.lock);
 	snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ",
 			dev->brightness->cur.val,
 			dev->contrast->cur.val,
@@ -508,7 +508,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
 			dev->int_menu->qmenu_int[dev->int_menu->cur.val],
 			dev->int_menu->cur.val);
 	gen_text(dev, vbuf, line++ * 16, 16, str);
-	mutex_unlock(&dev->ctrl_handler.lock);
+	mutex_unlock(dev->ctrl_handler.lock);
 	gen_text(dev, vbuf, line++ * 16, 16, str);
 	if (dev->button_pressed) {
 		dev->button_pressed--;
include/media/v4l2-ctrls.h +6 -3
index 533315b..71abac0 100644
@@ -168,7 +168,9 @@ struct v4l2_ctrl_ref {
 /** struct v4l2_ctrl_handler - The control handler keeps track of all the
   * controls: both the controls owned by the handler and those inherited
   * from other handlers.
+  * @_lock:	Default for "lock".
   * @lock:	Lock to control access to this handler and its controls.
+  *		May be replaced by the user right after init.
   * @ctrls:	The list of controls owned by this handler.
   * @ctrl_refs:	The list of control references.
   * @cached:	The last found control reference. It is common that the same
@@ -179,7 +181,8 @@ struct v4l2_ctrl_ref {
   * @error:	The error code of the first failed control addition.
   */
 struct v4l2_ctrl_handler {
-	struct mutex lock;
+	struct mutex _lock;
+	struct mutex *lock;
 	struct list_head ctrls;
 	struct list_head ctrl_refs;
 	struct v4l2_ctrl_ref *cached;
@@ -456,7 +459,7 @@ void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed);
   */
 static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl)
 {
-	mutex_lock(&ctrl->handler->lock);
+	mutex_lock(ctrl->handler->lock);
 }
 
 /** v4l2_ctrl_lock() - Helper function to unlock the handler
@@ -465,7 +468,7 @@ static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl)
   */
 static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl)
 {
-	mutex_unlock(&ctrl->handler->lock);
+	mutex_unlock(ctrl->handler->lock);
 }
 
 /** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver.
Signature · 1 line
1.7.2.5
#29 lore raw

Re: [PATCH v5 18/35] v4l: Allow changing control handler lock

Hi Sakari,

Quoted 11 lines · Sakari Ailus

Allow choosing the lock used by the control handler. This may be handy sometimes when a driver providing multiple subdevs does not want to use several locks to serialise its functions.

---
 drivers/media/video/adp1653.c    |    8 +++---
 drivers/media/video/v4l2-ctrls.c |   39 +++++++++++++++++++------------------
 drivers/media/video/vivi.c       |    4 +-
 include/media/v4l2-ctrls.h       |    9 +++++--
 4 files changed, 32 insertions(+), 28 deletions(-)

...

Quoted 15 lines
include/media/v4l2-ctrls.h +2 -0
index 533315b..71abac0 100644
@@ -168,7 +168,9 @@ struct v4l2_ctrl_ref {
 /** struct v4l2_ctrl_handler - The control handler keeps track of all the
   * controls: both the controls owned by the handler and those inherited
   * from other handlers.
+  * @_lock:	Default for "lock".
   * @lock:	Lock to control access to this handler and its controls.
+  *		May be replaced by the user right after init.
   * @ctrls:	The list of controls owned by this handler.
   * @ctrl_refs:	The list of control references.
   * @cached:	The last found control reference. It is common that the same

include/media/v4l2-ctrls.h struct v4l2_ctrl_ref { · line 185

Quoted 6 lines
include/media/v4l2-ctrls.h +2 -1
@@ -179,7 +181,8 @@ struct v4l2_ctrl_ref {
   * @error:	The error code of the first failed control addition.
   */
 struct v4l2_ctrl_handler {
-	struct mutex lock;
+	struct mutex _lock;
+	struct mutex *lock;

I think we have an issue here. All drivers that reference ctrl_handler.lock directly need to be updated, since the 'lock' member of struct v4l2_ctrl_handler is no a pointer. So insted

mutex_lock(&ctrl_handler.lock);

they should now do

mutex_lock(ctrl_handler.lock);

Or am I missing something ?

For example, I'm getting following error:

drivers/media/video/s5p-fimc/fimc-core.c: In function ‘fimc_ctrls_activate’:
drivers/media/video/s5p-fimc/fimc-core.c:678: warning: passing argument 1 of ‘mutex_lock’ from incompatible pointer type include/linux/mutex.h:152: note: expected ‘struct mutex *’ but argument is of type ‘struct mutex **’ drivers/media/video/s5p-fimc/fimc-core.c:697: warning: passing argument 1 of ‘mutex_unlock’ from incompatible pointer type include/linux/mutex.h:169: note: expected ‘struct mutex *’ but argument is of type ‘struct mutex **’

AFAICT only vivi and s5p-fimc drivers use the control handler lock directly, so I can prepare a patch updating those drivers.

Quoted 13 lines
include/media/v4l2-ctrls.h +1 -1
 	struct list_head ctrls;
 	struct list_head ctrl_refs;
 	struct v4l2_ctrl_ref *cached;
@@ -456,7 +459,7 @@ void v4l2_ctrl_grab(struct v4l2_ctrl *ctrl, bool grabbed);
   */
 static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl)
 {
-	mutex_lock(&ctrl->handler->lock);
+	mutex_lock(ctrl->handler->lock);
 }
 
 /** v4l2_ctrl_lock() - Helper function to unlock the handler

include/media/v4l2-ctrls.h static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl) · line 474

Quoted 8 lines
include/media/v4l2-ctrls.h +1 -1
@@ -465,7 +468,7 @@ static inline void v4l2_ctrl_lock(struct v4l2_ctrl *ctrl)
   */
 static inline void v4l2_ctrl_unlock(struct v4l2_ctrl *ctrl)
 {
-	mutex_unlock(&ctrl->handler->lock);
+	mutex_unlock(ctrl->handler->lock);
 }
 
 /** v4l2_ctrl_g_ctrl() - Helper function to get the control's value from within a driver.

--

Regards,
Sylwester

#30 lore raw

Re: [PATCH v5 18/35] v4l: Allow changing control handler lock

Hi Sylwester,

Quoted 51 lines · Sylwester Nawrocki

Hi Sakari,

Quoted 11 lines · Sakari Ailus

Allow choosing the lock used by the control handler. This may be handy sometimes when a driver providing multiple subdevs does not want to use several locks to serialise its functions.

---
  drivers/media/video/adp1653.c    |    8 +++---
  drivers/media/video/v4l2-ctrls.c |   39 +++++++++++++++++++------------------
  drivers/media/video/vivi.c       |    4 +-
  include/media/v4l2-ctrls.h       |    9 +++++--
  4 files changed, 32 insertions(+), 28 deletions(-)

...

Quoted 15 lines
include/media/v4l2-ctrls.h +2 -0
index 533315b..71abac0 100644
@@ -168,7 +168,9 @@ struct v4l2_ctrl_ref {
  /** struct v4l2_ctrl_handler - The control handler keeps track of all the
    * controls: both the controls owned by the handler and those inherited
    * from other handlers.
+  * @_lock:	Default for "lock".
    * @lock:	Lock to control access to this handler and its controls.
+  *		May be replaced by the user right after init.
    * @ctrls:	The list of controls owned by this handler.
    * @ctrl_refs:	The list of control references.
    * @cached:	The last found control reference. It is common that the same

include/media/v4l2-ctrls.h struct v4l2_ctrl_ref { · line 185

Quoted 6 lines
include/media/v4l2-ctrls.h +2 -1
@@ -179,7 +181,8 @@ struct v4l2_ctrl_ref {
    * @error:	The error code of the first failed control addition.
    */
  struct v4l2_ctrl_handler {
-	struct mutex lock;
+	struct mutex _lock;
+	struct mutex *lock;

I think we have an issue here. All drivers that reference ctrl_handler.lock directly need to be updated, since the 'lock' member of struct v4l2_ctrl_handler is no a pointer. So insted

mutex_lock(&ctrl_handler.lock);

they should now do

mutex_lock(ctrl_handler.lock);

Or am I missing something ?

For example, I'm getting following error:

Quoted 8 lines

drivers/media/video/s5p-fimc/fimc-core.c: In function ‘fimc_ctrls_activate’:
drivers/media/video/s5p-fimc/fimc-core.c:678: warning: passing argument 1 of ‘mutex_lock’ from incompatible pointer type include/linux/mutex.h:152: note: expected ‘struct mutex *’ but argument is of type ‘struct mutex **’ drivers/media/video/s5p-fimc/fimc-core.c:697: warning: passing argument 1 of ‘mutex_unlock’ from incompatible pointer type include/linux/mutex.h:169: note: expected ‘struct mutex *’ but argument is of type ‘struct mutex **’

AFAICT only vivi and s5p-fimc drivers use the control handler lock directly, so I can prepare a patch updating those drivers.

Ooops. The patch included the changes for adp1653 and vivi which I found to be the only drivers using the lock directly. I somehow missed s5p-fimc --- sorry about that.

Regards,

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

Re: [PATCH v5 18/35] v4l: Allow changing control handler lock

Quoted 3 lines · Sakari Ailus

Ooops. The patch included the changes for adp1653 and vivi which I found to be the only drivers using the lock directly. I somehow missed s5p-fimc --- sorry about that.

It's all right, no big deal. I'll make a patch to correct this.

Signature · 2 lines
Regards
Sylwester
#32 lore raw

Re: [PATCH v5 18/35] v4l: Allow changing control handler lock

In reply to Sylwester Nawrocki
Quoted 51 lines · Sylwester Nawrocki

Hi Sakari,

Quoted 11 lines · Sakari Ailus

Allow choosing the lock used by the control handler. This may be handy sometimes when a driver providing multiple subdevs does not want to use several locks to serialise its functions.

---
 drivers/media/video/adp1653.c    |    8 +++---
 drivers/media/video/v4l2-ctrls.c |   39 +++++++++++++++++++------------------
 drivers/media/video/vivi.c       |    4 +-
 include/media/v4l2-ctrls.h       |    9 +++++--
 4 files changed, 32 insertions(+), 28 deletions(-)

...

Quoted 15 lines
include/media/v4l2-ctrls.h +2 -0
index 533315b..71abac0 100644
@@ -168,7 +168,9 @@ struct v4l2_ctrl_ref {
 /** struct v4l2_ctrl_handler - The control handler keeps track of all the
   * controls: both the controls owned by the handler and those inherited
   * from other handlers.
+  * @_lock:	Default for "lock".
   * @lock:	Lock to control access to this handler and its controls.
+  *		May be replaced by the user right after init.
   * @ctrls:	The list of controls owned by this handler.
   * @ctrl_refs:	The list of control references.
   * @cached:	The last found control reference. It is common that the same

include/media/v4l2-ctrls.h struct v4l2_ctrl_ref { · line 185

Quoted 6 lines
include/media/v4l2-ctrls.h +2 -1
@@ -179,7 +181,8 @@ struct v4l2_ctrl_ref {
   * @error:	The error code of the first failed control addition.
   */
 struct v4l2_ctrl_handler {
-	struct mutex lock;
+	struct mutex _lock;
+	struct mutex *lock;

I think we have an issue here. All drivers that reference ctrl_handler.lock directly need to be updated, since the 'lock' member of struct v4l2_ctrl_handler is now a pointer. So instead

mutex_lock(&ctrl_handler.lock);

they should now do

mutex_lock(ctrl_handler.lock);

Or am I missing something ?

For example, I'm getting following error:

Quoted 8 lines

drivers/media/video/s5p-fimc/fimc-core.c: In function ‘fimc_ctrls_activate’:
drivers/media/video/s5p-fimc/fimc-core.c:678: warning: passing argument 1 of ‘mutex_lock’ from incompatible pointer type include/linux/mutex.h:152: note: expected ‘struct mutex *’ but argument is of type ‘struct mutex **’ drivers/media/video/s5p-fimc/fimc-core.c:697: warning: passing argument 1 of ‘mutex_unlock’ from incompatible pointer type include/linux/mutex.h:169: note: expected ‘struct mutex *’ but argument is of type ‘struct mutex **’

AFAICT only vivi and s5p-fimc drivers use the control handler lock directly, so I can prepare a patch updating those drivers.

OK, vivi and adp1653 are already modified in this patch, so s5p-fimc seems the only one left. I'll fix that.

Regards,
Sylwester

#33 lore raw

PATCH v5 19/35 omap3isp: Support additional in-memory compressed bayer formats

In reply to Sakari Ailus

This also prevents accessing NULL pointer in csi2_try_format().

---
 drivers/media/video/omap3isp/ispvideo.c |   13 +++++++++++++
 1 files changed, 13 insertions(+), 0 deletions(-)
drivers/media/video/omap3isp/ispvideo.c +13 -0
index b020700..c191f13 100644
@@ -46,6 +46,10 @@
  * Helper functions
  */
 
+/*
+ * NOTE: When adding new media bus codes, always remember to add
+ * corresponding in-memory formats to the table below!!!
+ */
 static struct isp_format_info formats[] = {
 	{ V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
 	  V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
@@ -68,9 +72,18 @@ static struct isp_format_info formats[] = {
 	{ V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
 	  V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
 	  V4L2_PIX_FMT_SRGGB8, 8, },
+	{ V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8, V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
+	  V4L2_MBUS_FMT_SBGGR10_1X10, 0,
+	  V4L2_PIX_FMT_SBGGR10DPCM8, 8, },
+	{ V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8, V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
+	  V4L2_MBUS_FMT_SGBRG10_1X10, 0,
+	  V4L2_PIX_FMT_SGBRG10DPCM8, 8, },
 	{ V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
 	  V4L2_MBUS_FMT_SGRBG10_1X10, 0,
 	  V4L2_PIX_FMT_SGRBG10DPCM8, 8, },
+	{ V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8, V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8,
+	  V4L2_MBUS_FMT_SRGGB10_1X10, 0,
+	  V4L2_PIX_FMT_SRGGB10DPCM8, 8, },
 	{ V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10,
 	  V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8,
 	  V4L2_PIX_FMT_SBGGR10, 10, },
Signature · 1 line
1.7.2.5
#34 lore raw

PATCH v5 20/35 omap3isp: Move definitions required by board code under include/media.

In reply to Sakari Ailus

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 d96603e..2e78041 100644
@@ -237,10 +237,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 042849a..3f4928d 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
#35 lore raw

PATCH v5 21/35 omap3: add definition for CONTROL_CAMERA_PHY_CTRL

In reply to Sakari Ailus

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 0ba68d3..f3acf09 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
#36 lore raw

PATCH v5 22/35 omap3isp: Move setting constaints above media_entity_pipeline_start

In reply to Sakari Ailus

The clock rate for l3_ick will soon be read during pipeline validation which is now part of media_entity_pipeline_start(). For that reason we set constraints earlier on.

---
 drivers/media/video/omap3isp/ispvideo.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)
drivers/media/video/omap3isp/ispvideo.c +7 -7
index c191f13..b0d541b 100644
@@ -304,8 +304,6 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
 	struct v4l2_subdev *subdev;
 	int ret;
 
-	pipe->max_rate = pipe->l3_ick;
-
 	subdev = isp_video_remote_subdev(pipe->output, NULL);
 	if (subdev == NULL)
 		return -EPIPE;
@@ -993,6 +991,12 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	 */
 	pipe = video->video.entity.pipe
 	     ? to_isp_pipeline(&video->video.entity) : &video->pipe;
+
+	if (video->isp->pdata->set_constraints)
+		video->isp->pdata->set_constraints(video->isp, true);
+	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
+	pipe->max_rate = pipe->l3_ick;
+
 	media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
 
 	/* Verify that the currently configured format matches the output of
@@ -1025,10 +1029,6 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 		pipe->output = far_end;
 	}
 
-	if (video->isp->pdata->set_constraints)
-		video->isp->pdata->set_constraints(video->isp, true);
-	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
-
 	/* Validate the pipeline and update its state. */
 	ret = isp_video_validate_pipeline(pipe);
 	if (ret < 0)
@@ -1074,9 +1074,9 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 error:
 	if (ret < 0) {
 		omap3isp_video_queue_streamoff(&vfh->queue);
+		media_entity_pipeline_stop(&video->video.entity);
 		if (video->isp->pdata->set_constraints)
 			video->isp->pdata->set_constraints(video->isp, false);
-		media_entity_pipeline_stop(&video->video.entity);
 		/* The DMA queue must be emptied here, otherwise CCDC interrupts
 		 * that will get triggered the next time the CCDC is powered up
 		 * will try to access buffers that might have been freed but
Signature · 1 line
1.7.2.5
#37 lore raw

PATCH v5 23/35 omap3isp: Assume media_entity_pipeline_start may fail

In reply to Sakari Ailus

Since media_entity_pipeline_start() now does link validation, it may actually fail. Perform the error handling.

---
 drivers/media/video/omap3isp/ispvideo.c |   52 ++++++++++++++++--------------
 1 files changed, 28 insertions(+), 24 deletions(-)
drivers/media/video/omap3isp/ispvideo.c +28 -24
index b0d541b..d34f690 100644
@@ -997,14 +997,16 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
 	pipe->max_rate = pipe->l3_ick;
 
-	media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
+	ret = media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
+	if (ret < 0)
+		goto err_pipeline_start;
 
 	/* Verify that the currently configured format matches the output of
 	 * the connected subdev.
 	 */
 	ret = isp_video_check_format(video, vfh);
 	if (ret < 0)
-		goto error;
+		goto err_check_format;
 
 	video->bpl_padding = ret;
 	video->bpl_value = vfh->format.fmt.pix.bytesperline;
@@ -1021,7 +1023,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	} else {
 		if (far_end == NULL) {
 			ret = -EPIPE;
-			goto error;
+			goto err_check_format;
 		}
 
 		state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
@@ -1032,7 +1034,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	/* Validate the pipeline and update its state. */
 	ret = isp_video_validate_pipeline(pipe);
 	if (ret < 0)
-		goto error;
+		goto err_check_format;
 
 	pipe->error = false;
 
@@ -1054,7 +1056,7 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 
 	ret = omap3isp_video_queue_streamon(&vfh->queue);
 	if (ret < 0)
-		goto error;
+		goto err_check_format;
 
 	/* In sensor-to-memory mode, the stream can be started synchronously
 	 * to the stream on command. In memory-to-memory mode, it will be
@@ -1064,32 +1066,34 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 		ret = omap3isp_pipeline_set_stream(pipe,
 					      ISP_PIPELINE_STREAM_CONTINUOUS);
 		if (ret < 0)
-			goto error;
+			goto err_set_stream;
 		spin_lock_irqsave(&video->queue->irqlock, flags);
 		if (list_empty(&video->dmaqueue))
 			video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
 		spin_unlock_irqrestore(&video->queue->irqlock, flags);
 	}
 
-error:
-	if (ret < 0) {
-		omap3isp_video_queue_streamoff(&vfh->queue);
-		media_entity_pipeline_stop(&video->video.entity);
-		if (video->isp->pdata->set_constraints)
-			video->isp->pdata->set_constraints(video->isp, false);
-		/* The DMA queue must be emptied here, otherwise CCDC interrupts
-		 * that will get triggered the next time the CCDC is powered up
-		 * will try to access buffers that might have been freed but
-		 * still present in the DMA queue. This can easily get triggered
-		 * if the above omap3isp_pipeline_set_stream() call fails on a
-		 * system with a free-running sensor.
-		 */
-		INIT_LIST_HEAD(&video->dmaqueue);
-		video->queue = NULL;
-	}
+	video->streaming = 1;
+
+	mutex_unlock(&video->stream_lock);
+	return 0;
 
-	if (!ret)
-		video->streaming = 1;
+err_set_stream:
+	omap3isp_video_queue_streamoff(&vfh->queue);
+err_check_format:
+	media_entity_pipeline_stop(&video->video.entity);
+err_pipeline_start:
+	if (video->isp->pdata->set_constraints)
+		video->isp->pdata->set_constraints(video->isp, false);
+	/* The DMA queue must be emptied here, otherwise CCDC interrupts that
+	 * will get triggered the next time the CCDC is powered up will try to
+	 * access buffers that might have been freed but still present in the
+	 * DMA queue. This can easily get triggered if the above
+	 * omap3isp_pipeline_set_stream() call fails on a system with a
+	 * free-running sensor.
+	 */
+	INIT_LIST_HEAD(&video->dmaqueue);
+	video->queue = NULL;
 
 	mutex_unlock(&video->stream_lock);
 	return ret;
Signature · 1 line
1.7.2.5
maintainer Acked-by on v5 23/35
#38 lore raw

Re: [PATCH v5 23/35] omap3isp: Assume media_entity_pipeline_start may fail

Hi Sakari,

Thanks for the patch.

Quoted 4 lines · On Tuesday 06 March 2012 18:33:04 Sakari Ailus wrote:

Since media_entity_pipeline_start() now does link validation, it may actually fail. Perform the error handling.

Signature · 3 lines
Regards,

Laurent Pinchart
#39 lore raw

PATCH v5 24/35 omap3isp: Add lane configuration to platform data

In reply to Sakari Ailus

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                 |   25 +++++++++++++++++++++++++
 2 files changed, 27 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 +25 -0
index 3f4928d..4d94be5 100644
@@ -91,6 +91,29 @@ enum {
 };
 
 /**
+ * struct isp_csiphy_lane: CCP2/CSI2 lane position and polarity
+ * @pos: position of the lane
+ * @pol: polarity of the lane
+ */
+struct isp_csiphy_lane {
+	u8 pos;
+	u8 pol;
+};
+
+#define ISP_CSIPHY1_NUM_DATA_LANES	1
+#define ISP_CSIPHY2_NUM_DATA_LANES	2
+
+/**
+ * struct isp_csiphy_lanes_cfg - CCP2/CSI2 lane configuration
+ * @data: Configuration of one or two data lanes
+ * @clk: Clock lane configuration
+ */
+struct isp_csiphy_lanes_cfg {
+	struct isp_csiphy_lane data[ISP_CSIPHY2_NUM_DATA_LANES];
+	struct isp_csiphy_lane clk;
+};
+
+/**
  * struct isp_ccp2_platform_data - CCP2 interface platform data
  * @strobe_clk_pol: Strobe/clock polarity
  *		0 - Non Inverted, 1 - Inverted
@@ -109,6 +132,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;
 };
 
 /**
@@ -119,6 +143,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
#40 lore raw

PATCH v5 25/35 omap3isp: Collect entities that are part of the pipeline

In reply to Sakari Ailus

Collect entities which are part of the pipeline into a single bit mask.

---
 drivers/media/video/omap3isp/ispvideo.c |    9 +++++++++
 drivers/media/video/omap3isp/ispvideo.h |    1 +
 2 files changed, 10 insertions(+), 0 deletions(-)
drivers/media/video/omap3isp/ispvideo.c +9 -0
index d34f690..4bc9cca 100644
@@ -970,6 +970,8 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 {
 	struct isp_video_fh *vfh = to_isp_video_fh(fh);
 	struct isp_video *video = video_drvdata(file);
+	struct media_entity_graph graph;
+	struct media_entity *entity;
 	enum isp_pipeline_state state;
 	struct isp_pipeline *pipe;
 	struct isp_video *far_end;
@@ -992,6 +994,8 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	pipe = video->video.entity.pipe
 	     ? to_isp_pipeline(&video->video.entity) : &video->pipe;
 
+	pipe->entities = 0;
+
 	if (video->isp->pdata->set_constraints)
 		video->isp->pdata->set_constraints(video->isp, true);
 	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
@@ -1001,6 +1005,11 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	if (ret < 0)
 		goto err_pipeline_start;
 
+	entity = &video->video.entity;
+	media_entity_graph_walk_start(&graph, entity);
+	while ((entity = media_entity_graph_walk_next(&graph)))
+		pipe->entities |= 1 << entity->id;
+
 	/* Verify that the currently configured format matches the output of
 	 * the connected subdev.
 	 */
drivers/media/video/omap3isp/ispvideo.h +1 -0
index d91bdb91..0423c9d 100644
@@ -96,6 +96,7 @@ struct isp_pipeline {
 	enum isp_pipeline_stream_state stream_state;
 	struct isp_video *input;
 	struct isp_video *output;
+	u32 entities;
 	unsigned long l3_ick;
 	unsigned int max_rate;
 	atomic_t frame_number;
Signature · 1 line
1.7.2.5
maintainer
#41 lore raw

Re: [PATCH v5 25/35] omap3isp: Collect entities that are part of the pipeline

Hi Sakari,

Thanks for the patch.

Quoted 23 lines · On Tuesday 06 March 2012 18:33:06 Sakari Ailus wrote:

Collect entities which are part of the pipeline into a single bit mask.

---
 drivers/media/video/omap3isp/ispvideo.c |    9 +++++++++
 drivers/media/video/omap3isp/ispvideo.h |    1 +
 2 files changed, 10 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.c index d34f690..4bc9cca 100644

drivers/media/video/omap3isp/ispvideo.c +2 -0
@@ -970,6 +970,8 @@ isp_video_streamon(struct file *file, void *fh, enum
 v4l2_buf_type type) {
 	struct isp_video_fh *vfh = to_isp_video_fh(fh);
 	struct isp_video *video = video_drvdata(file);
+	struct media_entity_graph graph;
+	struct media_entity *entity;
 	enum isp_pipeline_state state;
 	struct isp_pipeline *pipe;
 	struct isp_video *far_end;
@@ -992,6 +994,8 @@ isp_video_streamon(struct file *file, void *fh, enum

v4l2_buf_type type) pipe = video->video.entity.pipe

drivers/media/video/omap3isp/ispvideo.c isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) · line 998

Quoted 4 lines
drivers/media/video/omap3isp/ispvideo.c +2 -0
 	     ? to_isp_pipeline(&video->video.entity) : &video->pipe;
 
+	pipe->entities = 0;
+

This could be move right before the graph walk code below to keep both parts together. However, pipe->entities would then be invalid (instead of always 0) in the link validation operations. That can be considered as an issue, so I'm fine if you prefer leaving this assignment here.

drivers/media/video/omap3isp/ispvideo.c isp_video_streamon(struct file *file, void *fh, enum · line 1012

Quoted 12 lines
drivers/media/video/omap3isp/ispvideo.c +5 -0
 	if (video->isp->pdata->set_constraints)
 		video->isp->pdata->set_constraints(video->isp, true);
 	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
@@ -1001,6 +1005,11 @@ isp_video_streamon(struct file *file, void *fh, enum
 v4l2_buf_type type) if (ret < 0)
 		goto err_pipeline_start;
 
+	entity = &video->video.entity;
+	media_entity_graph_walk_start(&graph, entity);
+	while ((entity = media_entity_graph_walk_next(&graph)))
+		pipe->entities |= 1 << entity->id;
+

To avoid walking the graph one more time, what about moving this to isp_video_far_end() where we already walk the graph (and moving the isp_video_far_end() call earlier in this function) ? You could possible rename isp_video_far_end() to something a bit more in line with its new purpose then.

Quoted 15 lines
drivers/media/video/omap3isp/ispvideo.c +0 -0
 	/* Verify that the currently configured format matches the output of
 	 * the connected subdev.
 	 */
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.h index d91bdb91..0423c9d 100644

drivers/media/video/omap3isp/ispvideo.h +1 -0
@@ -96,6 +96,7 @@ struct isp_pipeline {
 	enum isp_pipeline_stream_state stream_state;
 	struct isp_video *input;
 	struct isp_video *output;
+	u32 entities;
 	unsigned long l3_ick;
 	unsigned int max_rate;
 	atomic_t frame_number;
Signature · 3 lines
Regards,

Laurent Pinchart
#42 lore raw

Re: [PATCH v5 25/35] omap3isp: Collect entities that are part of the pipeline

Hi Laurent,

Quoted 26 lines · Laurent Pinchart
Quoted 25 lines · On Tuesday 06 March 2012 18:33:06 Sakari Ailus wrote:

Collect entities which are part of the pipeline into a single bit mask.

---
 drivers/media/video/omap3isp/ispvideo.c |    9 +++++++++
 drivers/media/video/omap3isp/ispvideo.h |    1 +
 2 files changed, 10 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.c index d34f690..4bc9cca 100644

drivers/media/video/omap3isp/ispvideo.c +2 -0
@@ -970,6 +970,8 @@ isp_video_streamon(struct file *file, void *fh, enum
 v4l2_buf_type type) {
 	struct isp_video_fh *vfh = to_isp_video_fh(fh);
 	struct isp_video *video = video_drvdata(file);
+	struct media_entity_graph graph;
+	struct media_entity *entity;
 	enum isp_pipeline_state state;
 	struct isp_pipeline *pipe;
 	struct isp_video *far_end;
@@ -992,6 +994,8 @@ isp_video_streamon(struct file *file, void *fh, enum

v4l2_buf_type type) pipe = video->video.entity.pipe
? to_isp_pipeline(&video->video.entity) : &video->pipe;

Quoted 7 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) · line 998

Quoted 2 lines
drivers/media/video/omap3isp/ispvideo.c +2 -0
+	pipe->entities = 0;
+

This could be move right before the graph walk code below to keep both parts together. However, pipe->entities would then be invalid (instead of always 0) in the link validation operations. That can be considered as an issue, so I'm fine if you prefer leaving this assignment here.

That's what I also thought, so let's leave it there.

Quoted 7 lines
Quoted 7 lines
drivers/media/video/omap3isp/ispvideo.c +0 -0
 	if (video->isp->pdata->set_constraints)
 		video->isp->pdata->set_constraints(video->isp, true);
 	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
@@ -1001,6 +1005,11 @@ isp_video_streamon(struct file *file, void *fh, enum
 v4l2_buf_type type) if (ret < 0)
 		goto err_pipeline_start;
 
Quoted 10 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type) · line 1012

Quoted 5 lines
drivers/media/video/omap3isp/ispvideo.c +5 -0
+	entity = &video->video.entity;
+	media_entity_graph_walk_start(&graph, entity);
+	while ((entity = media_entity_graph_walk_next(&graph)))
+		pipe->entities |= 1 << entity->id;
+

To avoid walking the graph one more time, what about moving this to isp_video_far_end() where we already walk the graph (and moving the isp_video_far_end() call earlier in this function) ? You could possible rename isp_video_far_end() to something a bit more in line with its new purpose then.

isp_video_get_graph_data()?

Signature · 2 lines
Sakari Ailus
e-mail: [email protected]	jabber/XMPP/Gmail: [email protected]
#43 lore raw

PATCH v5 25/35 omap3isp: Collect entities that are part of the pipeline

Collect entities which are part of the pipeline into a single bit mask.

---
 drivers/media/video/omap3isp/ispvideo.c |   48 ++++++++++++++++---------------
 drivers/media/video/omap3isp/ispvideo.h |    2 +
 2 files changed, 27 insertions(+), 23 deletions(-)
drivers/media/video/omap3isp/ispvideo.c +25 -23
index d34f690..7411076 100644
@@ -255,8 +255,9 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad)
 }
 
 /* Return a pointer to the ISP video instance at the far end of the pipeline. */
-static struct isp_video *
-isp_video_far_end(struct isp_video *video)
+static int isp_video_get_graph_data(struct isp_video *video,
+				    struct isp_pipeline *pipe,
+				    enum isp_pipeline_state *state)
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
@@ -267,6 +268,8 @@ isp_video_far_end(struct isp_video *video)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
+		pipe->entities |= 1 << entity->id;
+
 		if (entity == &video->video.entity)
 			continue;
 
@@ -281,7 +284,21 @@ isp_video_far_end(struct isp_video *video)
 	}
 
 	mutex_unlock(&mdev->graph_mutex);
-	return far_end;
+
+	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		*state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
+		pipe->input = far_end;
+		pipe->output = video;
+	} else {
+		if (far_end == NULL)
+			return -EPIPE;
+
+		*state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
+		pipe->input = video;
+		pipe->output = far_end;
+	}
+
+	return 0;
 }
 
 /*
@@ -972,7 +989,6 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	struct isp_video *video = video_drvdata(file);
 	enum isp_pipeline_state state;
 	struct isp_pipeline *pipe;
-	struct isp_video *far_end;
 	unsigned long flags;
 	int ret;
 
@@ -992,6 +1008,8 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	pipe = video->video.entity.pipe
 	     ? to_isp_pipeline(&video->video.entity) : &video->pipe;
 
+	pipe->entities = 0;
+
 	if (video->isp->pdata->set_constraints)
 		video->isp->pdata->set_constraints(video->isp, true);
 	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
@@ -1011,25 +1029,9 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	video->bpl_padding = ret;
 	video->bpl_value = vfh->format.fmt.pix.bytesperline;
 
-	/* Find the ISP video node connected at the far end of the pipeline and
-	 * update the pipeline.
-	 */
-	far_end = isp_video_far_end(video);
-
-	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
-		pipe->input = far_end;
-		pipe->output = video;
-	} else {
-		if (far_end == NULL) {
-			ret = -EPIPE;
-			goto err_check_format;
-		}
-
-		state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
-		pipe->input = video;
-		pipe->output = far_end;
-	}
+	ret = isp_video_get_graph_data(video, pipe, &state);
+	if (ret < 0)
+		goto err_check_format;
 
 	/* Validate the pipeline and update its state. */
 	ret = isp_video_validate_pipeline(pipe);
drivers/media/video/omap3isp/ispvideo.h +2 -0
index d91bdb91..c9187cb 100644
@@ -88,6 +88,7 @@ enum isp_pipeline_state {
 /*
  * struct isp_pipeline - An ISP hardware pipeline
  * @error: A hardware error occurred during capture
+ * @entities: Bitmask of entities in the pipeline (indexed by entity ID)
  */
 struct isp_pipeline {
 	struct media_pipeline pipe;
@@ -96,6 +97,7 @@ struct isp_pipeline {
 	enum isp_pipeline_stream_state stream_state;
 	struct isp_video *input;
 	struct isp_video *output;
+	u32 entities;
 	unsigned long l3_ick;
 	unsigned int max_rate;
 	atomic_t frame_number;
Signature · 1 line
1.7.2.5
maintainer
#44 lore raw

Re: [PATCH v5.1 25/35] omap3isp: Collect entities that are part of the pipeline

Hi Sakari,

Thanks for the patch.

Quoted 26 lines · On Wednesday 07 March 2012 19:22:56 Sakari Ailus wrote:

Collect entities which are part of the pipeline into a single bit mask.

---
 drivers/media/video/omap3isp/ispvideo.c |   48
++++++++++++++++--------------- drivers/media/video/omap3isp/ispvideo.h |  
 2 +
 2 files changed, 27 insertions(+), 23 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.c index d34f690..7411076 100644

drivers/media/video/omap3isp/ispvideo.c +0 -0
@@ -255,8 +255,9 @@ isp_video_remote_subdev(struct isp_video *video, u32
 *pad) }
 
 /* Return a pointer to the ISP video instance at the far end of the

pipeline. */ -static struct isp_video *

drivers/media/video/omap3isp/ispvideo.c +3 -1
-isp_video_far_end(struct isp_video *video)
+static int isp_video_get_graph_data(struct isp_video *video,
+				    struct isp_pipeline *pipe,
+				    enum isp_pipeline_state *state)
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;

drivers/media/video/omap3isp/ispvideo.c isp_video_far_end(struct isp_video *video) · line 275

Quoted 8 lines
drivers/media/video/omap3isp/ispvideo.c +2 -0
@@ -267,6 +268,8 @@ isp_video_far_end(struct isp_video *video)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
+		pipe->entities |= 1 << entity->id;
+
 		if (entity == &video->video.entity)
 			continue;
 

The loop will stop as soon as it find a video node at the other end of the pipeline. As media_entity_graph_walk_next() doesn't guarantee any graph search order, you should avoid stopping the loop before having walked all entities, otherwise you could miss some.

Something like

        while ((entity = media_entity_graph_walk_next(&graph))) {
                struct isp_video *node;

                pipe->entities |= 1 << entity->id;

                if (entity == &video->video.entity)
                        continue;

                if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
                        continue;

                node = to_isp_video(media_entity_to_video_device(entity));
                if (node->type != video->type)
                        far_end = node;
        }

should do (feel free to rename node to something else, I have little imagination so late at night).

Quoted 89 lines
drivers/media/video/omap3isp/ispvideo.c +15 -2
@@ -281,7 +284,21 @@ isp_video_far_end(struct isp_video *video)
 	}
 
 	mutex_unlock(&mdev->graph_mutex);
-	return far_end;
+
+	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		*state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
+		pipe->input = far_end;
+		pipe->output = video;
+	} else {
+		if (far_end == NULL)
+			return -EPIPE;
+
+		*state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
+		pipe->input = video;
+		pipe->output = far_end;
+	}
+
+	return 0;
 }
 
 /*
@@ -972,7 +989,6 @@ isp_video_streamon(struct file *file, void *fh, enum
 v4l2_buf_type type) struct isp_video *video = video_drvdata(file);
 	enum isp_pipeline_state state;
 	struct isp_pipeline *pipe;
-	struct isp_video *far_end;
 	unsigned long flags;
 	int ret;
 
@@ -992,6 +1008,8 @@ isp_video_streamon(struct file *file, void *fh, enum

v4l2_buf_type type) pipe = video->video.entity.pipe

drivers/media/video/omap3isp/ispvideo.c +5 -19
 	     ? to_isp_pipeline(&video->video.entity) : &video->pipe;
 
+	pipe->entities = 0;
+
 	if (video->isp->pdata->set_constraints)
 		video->isp->pdata->set_constraints(video->isp, true);
 	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
@@ -1011,25 +1029,9 @@ isp_video_streamon(struct file *file, void *fh, enum
 v4l2_buf_type type) video->bpl_padding = ret;
 	video->bpl_value = vfh->format.fmt.pix.bytesperline;
 
-	/* Find the ISP video node connected at the far end of the pipeline and
-	 * update the pipeline.
-	 */
-	far_end = isp_video_far_end(video);
-
-	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
-		pipe->input = far_end;
-		pipe->output = video;
-	} else {
-		if (far_end == NULL) {
-			ret = -EPIPE;
-			goto err_check_format;
-		}
-
-		state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
-		pipe->input = video;
-		pipe->output = far_end;
-	}
+	ret = isp_video_get_graph_data(video, pipe, &state);
+	if (ret < 0)
+		goto err_check_format;
 
 	/* Validate the pipeline and update its state. */
 	ret = isp_video_validate_pipeline(pipe);
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.h index d91bdb91..c9187cb 100644

drivers/media/video/omap3isp/ispvideo.h +2 -0
@@ -88,6 +88,7 @@ enum isp_pipeline_state {
 /*
  * struct isp_pipeline - An ISP hardware pipeline
  * @error: A hardware error occurred during capture
+ * @entities: Bitmask of entities in the pipeline (indexed by entity ID)
  */
 struct isp_pipeline {
 	struct media_pipeline pipe;
@@ -96,6 +97,7 @@ struct isp_pipeline {
 	enum isp_pipeline_stream_state stream_state;
 	struct isp_video *input;
 	struct isp_video *output;
+	u32 entities;
 	unsigned long l3_ick;
 	unsigned int max_rate;
 	atomic_t frame_number;
Signature · 3 lines
Regards,

Laurent Pinchart
#45 lore raw

PATCH v5 25/35 omap3isp: Collect entities that are part of the pipeline

Collect entities which are part of the pipeline into a single bit mask.

---
 drivers/media/video/omap3isp/ispvideo.c |   61 +++++++++++++++++--------------
 drivers/media/video/omap3isp/ispvideo.h |    2 +
 2 files changed, 35 insertions(+), 28 deletions(-)
drivers/media/video/omap3isp/ispvideo.c +33 -28
index d34f690..8ce3c5b 100644
@@ -255,8 +255,9 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad)
 }
 
 /* Return a pointer to the ISP video instance at the far end of the pipeline. */
-static struct isp_video *
-isp_video_far_end(struct isp_video *video)
+static int isp_video_get_graph_data(struct isp_video *video,
+				    struct isp_pipeline *pipe,
+				    enum isp_pipeline_state *state)
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
@@ -267,21 +268,40 @@ isp_video_far_end(struct isp_video *video)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
+		struct isp_video *__video;
+
+		pipe->entities |= 1 << entity->id;
+
+		if (far_end != NULL)
+			continue;
+
 		if (entity == &video->video.entity)
 			continue;
 
 		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
 			continue;
 
-		far_end = to_isp_video(media_entity_to_video_device(entity));
-		if (far_end->type != video->type)
-			break;
-
-		far_end = NULL;
+		__video = to_isp_video(media_entity_to_video_device(entity));
+		if (__video->type != video->type)
+			far_end = __video;
 	}
 
 	mutex_unlock(&mdev->graph_mutex);
-	return far_end;
+
+	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		*state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
+		pipe->input = far_end;
+		pipe->output = video;
+	} else {
+		if (far_end == NULL)
+			return -EPIPE;
+
+		*state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
+		pipe->input = video;
+		pipe->output = far_end;
+	}
+
+	return 0;
 }
 
 /*
@@ -972,7 +992,6 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	struct isp_video *video = video_drvdata(file);
 	enum isp_pipeline_state state;
 	struct isp_pipeline *pipe;
-	struct isp_video *far_end;
 	unsigned long flags;
 	int ret;
 
@@ -992,6 +1011,8 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	pipe = video->video.entity.pipe
 	     ? to_isp_pipeline(&video->video.entity) : &video->pipe;
 
+	pipe->entities = 0;
+
 	if (video->isp->pdata->set_constraints)
 		video->isp->pdata->set_constraints(video->isp, true);
 	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
@@ -1011,25 +1032,9 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	video->bpl_padding = ret;
 	video->bpl_value = vfh->format.fmt.pix.bytesperline;
 
-	/* Find the ISP video node connected at the far end of the pipeline and
-	 * update the pipeline.
-	 */
-	far_end = isp_video_far_end(video);
-
-	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
-		pipe->input = far_end;
-		pipe->output = video;
-	} else {
-		if (far_end == NULL) {
-			ret = -EPIPE;
-			goto err_check_format;
-		}
-
-		state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
-		pipe->input = video;
-		pipe->output = far_end;
-	}
+	ret = isp_video_get_graph_data(video, pipe, &state);
+	if (ret < 0)
+		goto err_check_format;
 
 	/* Validate the pipeline and update its state. */
 	ret = isp_video_validate_pipeline(pipe);
drivers/media/video/omap3isp/ispvideo.h +2 -0
index d91bdb9..c9187cb 100644
@@ -88,6 +88,7 @@ enum isp_pipeline_state {
 /*
  * struct isp_pipeline - An ISP hardware pipeline
  * @error: A hardware error occurred during capture
+ * @entities: Bitmask of entities in the pipeline (indexed by entity ID)
  */
 struct isp_pipeline {
 	struct media_pipeline pipe;
@@ -96,6 +97,7 @@ struct isp_pipeline {
 	enum isp_pipeline_stream_state stream_state;
 	struct isp_video *input;
 	struct isp_video *output;
+	u32 entities;
 	unsigned long l3_ick;
 	unsigned int max_rate;
 	atomic_t frame_number;
Signature · 1 line
1.7.2.5
#46 lore raw

PATCH v5 25/35 omap3isp: Collect entities that are part of the pipeline

In reply to Laurent Pinchart

Collect entities which are part of the pipeline into a single bit mask.

---
since last version:

- state is set in isp_video_streamon() rather than isp_video_get_graph_data().
- Get information from all entities which was broken by the previous version.

 drivers/media/video/omap3isp/ispvideo.c |   57 +++++++++++++++++-------------
 drivers/media/video/omap3isp/ispvideo.h |    2 +
 2 files changed, 34 insertions(+), 25 deletions(-)
drivers/media/video/omap3isp/ispvideo.c +32 -25
index d34f690..d8a5250 100644
@@ -255,8 +255,8 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad)
 }
 
 /* Return a pointer to the ISP video instance at the far end of the pipeline. */
-static struct isp_video *
-isp_video_far_end(struct isp_video *video)
+static int isp_video_get_graph_data(struct isp_video *video,
+				    struct isp_pipeline *pipe)
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
@@ -267,21 +267,38 @@ isp_video_far_end(struct isp_video *video)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
+		struct isp_video *__video;
+
+		pipe->entities |= 1 << entity->id;
+
+		if (far_end != NULL)
+			continue;
+
 		if (entity == &video->video.entity)
 			continue;
 
 		if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
 			continue;
 
-		far_end = to_isp_video(media_entity_to_video_device(entity));
-		if (far_end->type != video->type)
-			break;
-
-		far_end = NULL;
+		__video = to_isp_video(media_entity_to_video_device(entity));
+		if (__video->type != video->type)
+			far_end = __video;
 	}
 
 	mutex_unlock(&mdev->graph_mutex);
-	return far_end;
+
+	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		pipe->input = far_end;
+		pipe->output = video;
+	} else {
+		if (far_end == NULL)
+			return -EPIPE;
+
+		pipe->input = video;
+		pipe->output = far_end;
+	}
+
+	return 0;
 }
 
 /*
@@ -972,7 +989,6 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	struct isp_video *video = video_drvdata(file);
 	enum isp_pipeline_state state;
 	struct isp_pipeline *pipe;
-	struct isp_video *far_end;
 	unsigned long flags;
 	int ret;
 
@@ -992,6 +1008,8 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	pipe = video->video.entity.pipe
 	     ? to_isp_pipeline(&video->video.entity) : &video->pipe;
 
+	pipe->entities = 0;
+
 	if (video->isp->pdata->set_constraints)
 		video->isp->pdata->set_constraints(video->isp, true);
 	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
@@ -1011,25 +1029,14 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	video->bpl_padding = ret;
 	video->bpl_value = vfh->format.fmt.pix.bytesperline;
 
-	/* Find the ISP video node connected at the far end of the pipeline and
-	 * update the pipeline.
-	 */
-	far_end = isp_video_far_end(video);
+	ret = isp_video_get_graph_data(video, pipe);
+	if (ret < 0)
+		goto err_check_format;
 
-	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
-		pipe->input = far_end;
-		pipe->output = video;
-	} else {
-		if (far_end == NULL) {
-			ret = -EPIPE;
-			goto err_check_format;
-		}
-
+	else
 		state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
-		pipe->input = video;
-		pipe->output = far_end;
-	}
 
 	/* Validate the pipeline and update its state. */
 	ret = isp_video_validate_pipeline(pipe);
drivers/media/video/omap3isp/ispvideo.h +2 -0
index d91bdb9..c9187cb 100644
@@ -88,6 +88,7 @@ enum isp_pipeline_state {
 /*
  * struct isp_pipeline - An ISP hardware pipeline
  * @error: A hardware error occurred during capture
+ * @entities: Bitmask of entities in the pipeline (indexed by entity ID)
  */
 struct isp_pipeline {
 	struct media_pipeline pipe;
@@ -96,6 +97,7 @@ struct isp_pipeline {
 	enum isp_pipeline_stream_state stream_state;
 	struct isp_video *input;
 	struct isp_video *output;
+	u32 entities;
 	unsigned long l3_ick;
 	unsigned int max_rate;
 	atomic_t frame_number;
Signature · 1 line
1.7.2.5
#48 lore raw

PATCH v5 25/35 omap3isp: Collect entities that are part of the pipeline

In reply to Laurent Pinchart

Collect entities which are part of the pipeline into a single bit mask.

---
 drivers/media/video/omap3isp/ispvideo.c |   48 ++++++++++++++++---------------
 drivers/media/video/omap3isp/ispvideo.h |    2 +
 2 files changed, 27 insertions(+), 23 deletions(-)
drivers/media/video/omap3isp/ispvideo.c +25 -23
index d34f690..7411076 100644
@@ -255,8 +255,9 @@ isp_video_remote_subdev(struct isp_video *video, u32 *pad)
 }
 
 /* Return a pointer to the ISP video instance at the far end of the pipeline. */
-static struct isp_video *
-isp_video_far_end(struct isp_video *video)
+static int isp_video_get_graph_data(struct isp_video *video,
+				    struct isp_pipeline *pipe,
+				    enum isp_pipeline_state *state)
 {
 	struct media_entity_graph graph;
 	struct media_entity *entity = &video->video.entity;
@@ -267,6 +268,8 @@ isp_video_far_end(struct isp_video *video)
 	media_entity_graph_walk_start(&graph, entity);
 
 	while ((entity = media_entity_graph_walk_next(&graph))) {
+		pipe->entities |= 1 << entity->id;
+
 		if (entity == &video->video.entity)
 			continue;
 
@@ -281,7 +284,21 @@ isp_video_far_end(struct isp_video *video)
 	}
 
 	mutex_unlock(&mdev->graph_mutex);
-	return far_end;
+
+	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+		*state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
+		pipe->input = far_end;
+		pipe->output = video;
+	} else {
+		if (far_end == NULL)
+			return -EPIPE;
+
+		*state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
+		pipe->input = video;
+		pipe->output = far_end;
+	}
+
+	return 0;
 }
 
 /*
@@ -972,7 +989,6 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	struct isp_video *video = video_drvdata(file);
 	enum isp_pipeline_state state;
 	struct isp_pipeline *pipe;
-	struct isp_video *far_end;
 	unsigned long flags;
 	int ret;
 
@@ -992,6 +1008,8 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	pipe = video->video.entity.pipe
 	     ? to_isp_pipeline(&video->video.entity) : &video->pipe;
 
+	pipe->entities = 0;
+
 	if (video->isp->pdata->set_constraints)
 		video->isp->pdata->set_constraints(video->isp, true);
 	pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
@@ -1011,25 +1029,9 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	video->bpl_padding = ret;
 	video->bpl_value = vfh->format.fmt.pix.bytesperline;
 
-	/* Find the ISP video node connected at the far end of the pipeline and
-	 * update the pipeline.
-	 */
-	far_end = isp_video_far_end(video);
-
-	if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
-		state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
-		pipe->input = far_end;
-		pipe->output = video;
-	} else {
-		if (far_end == NULL) {
-			ret = -EPIPE;
-			goto err_check_format;
-		}
-
-		state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
-		pipe->input = video;
-		pipe->output = far_end;
-	}
+	ret = isp_video_get_graph_data(video, pipe, &state);
+	if (ret < 0)
+		goto err_check_format;
 
 	/* Validate the pipeline and update its state. */
 	ret = isp_video_validate_pipeline(pipe);
drivers/media/video/omap3isp/ispvideo.h +2 -0
index d91bdb91..c9187cb 100644
@@ -88,6 +88,7 @@ enum isp_pipeline_state {
 /*
  * struct isp_pipeline - An ISP hardware pipeline
  * @error: A hardware error occurred during capture
+ * @entities: Bitmask of entities in the pipeline (indexed by entity ID)
  */
 struct isp_pipeline {
 	struct media_pipeline pipe;
@@ -96,6 +97,7 @@ struct isp_pipeline {
 	enum isp_pipeline_stream_state stream_state;
 	struct isp_video *input;
 	struct isp_video *output;
+	u32 entities;
 	unsigned long l3_ick;
 	unsigned int max_rate;
 	atomic_t frame_number;
Signature · 1 line
1.7.2.5
maintainer
#49 lore raw

Re: [PATCH v5 25/35] omap3isp: Collect entities that are part of the pipeline

In reply to Sakari Ailus

Hi Sakari,

Another comment.

Quoted 3 lines · On Tuesday 06 March 2012 18:33:06 Sakari Ailus wrote:

Collect entities which are part of the pipeline into a single bit mask.

[snip]

drivers/media/video/omap3isp/ispvideo.h struct isp_pipeline { · line 102

Quoted 12 lines
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.h index d91bdb91..0423c9d 100644

drivers/media/video/omap3isp/ispvideo.h +1 -0
@@ -96,6 +96,7 @@ struct isp_pipeline {
 	enum isp_pipeline_stream_state stream_state;
 	struct isp_video *input;
 	struct isp_video *output;
+	u32 entities;
 	unsigned long l3_ick;
 	unsigned int max_rate;
 	atomic_t frame_number;

Could you please update the structure documentation ?

@entities: Bitmask of entities in the pipeline (indexed by entity ID)

Signature · 3 lines
Regards,

Laurent Pinchart
#50 lore raw

Re: [PATCH v5 25/35] omap3isp: Collect entities that are part of the pipeline

Hi Laurent,

Quoted 26 lines · Laurent Pinchart

Hi Sakari,

Another comment.

Quoted 3 lines · On Tuesday 06 March 2012 18:33:06 Sakari Ailus wrote:

Collect entities which are part of the pipeline into a single bit mask.

[snip]

drivers/media/video/omap3isp/ispvideo.h struct isp_pipeline { · line 102

Quoted 12 lines
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.h index d91bdb91..0423c9d 100644

drivers/media/video/omap3isp/ispvideo.h +1 -0
@@ -96,6 +96,7 @@ struct isp_pipeline {
 	enum isp_pipeline_stream_state stream_state;
 	struct isp_video *input;
 	struct isp_video *output;
+	u32 entities;
 	unsigned long l3_ick;
 	unsigned int max_rate;
 	atomic_t frame_number;

Could you please update the structure documentation ?

Quoted 1 line

@entities: Bitmask of entities in the pipeline (indexed by entity ID)

Sure. I'll take that from your patch. ;-)

Signature · 2 lines
Sakari Ailus
e-mail: [email protected]	jabber/XMPP/Gmail: [email protected]
#51 lore raw

PATCH v5 26/35 omap3isp: Add information on external subdev to struct isp_pipeline

In reply to Sakari Ailus

Add pointer to external subdev, pixel rate of the external subdev and bpp of the format to struct isp_pipeline.

---
 drivers/media/video/omap3isp/ispvideo.h |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
drivers/media/video/omap3isp/ispvideo.h +3 -0
index 0423c9d..8c16156 100644
@@ -103,6 +103,9 @@ struct isp_pipeline {
 	bool do_propagation; /* of frame number */
 	bool error;
 	struct v4l2_fract max_timeperframe;
+	struct v4l2_subdev *external;
+	unsigned int external_rate;
+	unsigned int external_bpp;
 };
 
 #define to_isp_pipeline(__e) \
Signature · 1 line
1.7.2.5
#52 lore raw

PATCH v5 27/35 omap3isp: Introduce isp_video_check_external_subdevs()

In reply to Sakari Ailus

isp_video_check_external_subdevs() will retrieve external subdev's bits-per-pixel and pixel rate for the use of other ISP subdevs at streamon time. isp_video_check_external_subdevs() is called after pipeline validation.

---
 drivers/media/video/omap3isp/ispvideo.c |   75 +++++++++++++++++++++++++++++++
 1 files changed, 75 insertions(+), 0 deletions(-)
drivers/media/video/omap3isp/ispvideo.c +75 -0
index 4bc9cca..ef5c770 100644
@@ -934,6 +934,77 @@ isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
 					  file->f_flags & O_NONBLOCK);
 }
 
+static int isp_video_check_external_subdevs(struct isp_pipeline *pipe)
+{
+	struct isp_device *isp =
+		container_of(pipe, struct isp_video, pipe)->isp;
+	struct media_entity *ents[] = {
+		&isp->isp_csi2a.subdev.entity,
+		&isp->isp_csi2c.subdev.entity,
+		&isp->isp_ccp2.subdev.entity,
+		&isp->isp_ccdc.subdev.entity
+	};
+	struct media_pad *source_pad;
+	struct media_entity *source = NULL;
+	struct media_entity *sink;
+	struct v4l2_subdev_format fmt;
+	struct v4l2_ext_controls ctrls;
+	struct v4l2_ext_control ctrl;
+	int i;
+	int ret = 0;
+
+	for (i = 0; i < ARRAY_SIZE(ents); i++) {
+		/* Is the entity part of the pipeline? */
+		if (!(pipe->entities & (1 << ents[i]->id)))
+			continue;
+
+		/* ISP entities have always sink pad == 0. Find source. */
+		source_pad = media_entity_remote_source(&ents[i]->pads[0]);
+
+		if (source_pad == NULL)
+			continue;
+
+		source = source_pad->entity;
+		sink = ents[i];
+		break;
+	}
+
+	if (!source || media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
+		return 0;
+
+	pipe->external = media_entity_to_v4l2_subdev(source);
+
+	fmt.pad = source_pad->index;
+	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
+			       pad, get_fmt, NULL, &fmt);
+	BUG_ON(ret < 0);
+
+	pipe->external_bpp = omap3isp_video_format_info(
+		fmt.format.code)->bpp;
+
+	memset(&ctrls, 0, sizeof(ctrls));
+	memset(&ctrl, 0, sizeof(ctrl));
+
+	ctrl.id = V4L2_CID_PIXEL_RATE;
+
+	ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(ctrl.id);
+	ctrls.count = 1;
+	ctrls.controls = &ctrl;
+
+	ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
+	if (ret < 0) {
+		dev_warn(isp->dev,
+			 "no pixel rate control in subdev %s\n",
+			 pipe->external->name);
+		return ret;
+	}
+
+	pipe->external_rate = ctrl.value64;
+
+	return 0;
+}
+
 /*
  * Stream management
  *
@@ -1010,6 +1081,10 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	while ((entity = media_entity_graph_walk_next(&graph)))
 		pipe->entities |= 1 << entity->id;
 
+	ret = isp_video_check_external_subdevs(pipe);
+	if (ret < 0)
+		goto err_check_format;
+
 	/* Verify that the currently configured format matches the output of
 	 * the connected subdev.
 	 */
Signature · 1 line
1.7.2.5
maintainer
#53 lore raw

Re: [PATCH v5 27/35] omap3isp: Introduce isp_video_check_external_subdevs()

Hi Sakari,

Thanks for the patch.

Quoted 15 lines · On Tuesday 06 March 2012 18:33:08 Sakari Ailus wrote:

isp_video_check_external_subdevs() will retrieve external subdev's bits-per-pixel and pixel rate for the use of other ISP subdevs at streamon time. isp_video_check_external_subdevs() is called after pipeline validation.

---
 drivers/media/video/omap3isp/ispvideo.c |   75 ++++++++++++++++++++++++++++
 1 files changed, 75 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.c index 4bc9cca..ef5c770 100644

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct · line 940

Quoted 7 lines
drivers/media/video/omap3isp/ispvideo.c +4 -0
@@ -934,6 +934,77 @@ isp_video_dqbuf(struct file *file, void *fh, struct
 v4l2_buffer *b) file->f_flags & O_NONBLOCK);
 }
 
+static int isp_video_check_external_subdevs(struct isp_pipeline *pipe)
+{
+	struct isp_device *isp =
+		container_of(pipe, struct isp_video, pipe)->isp;

Any reason not to pass isp_device * from the caller to this function ?

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 953

Quoted 13 lines
drivers/media/video/omap3isp/ispvideo.c +13 -0
+	struct media_entity *ents[] = {
+		&isp->isp_csi2a.subdev.entity,
+		&isp->isp_csi2c.subdev.entity,
+		&isp->isp_ccp2.subdev.entity,
+		&isp->isp_ccdc.subdev.entity
+	};
+	struct media_pad *source_pad;
+	struct media_entity *source = NULL;
+	struct media_entity *sink;
+	struct v4l2_subdev_format fmt;
+	struct v4l2_ext_controls ctrls;
+	struct v4l2_ext_control ctrl;
+	int i;

i is allowed to be unsigned in this driver as well ;-)

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 963

Quoted 10 lines
drivers/media/video/omap3isp/ispvideo.c +10 -0
+	int ret = 0;
+
+	for (i = 0; i < ARRAY_SIZE(ents); i++) {
+		/* Is the entity part of the pipeline? */
+		if (!(pipe->entities & (1 << ents[i]->id)))
+			continue;
+
+		/* ISP entities have always sink pad == 0. Find source. */
+		source_pad = media_entity_remote_source(&ents[i]->pads[0]);
+

Don't you usually avoid blank lines between a variable assignment and checking it for an error condition ?

Quoted 8 lines
drivers/media/video/omap3isp/ispvideo.c +8 -0
+		if (source_pad == NULL)
+			continue;
+
+		source = source_pad->entity;
+		sink = ents[i];
+		break;
+	}
+

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 981

Quoted 10 lines
drivers/media/video/omap3isp/ispvideo.c +10 -0
+	if (!source || media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
+		return 0;
+
+	pipe->external = media_entity_to_v4l2_subdev(source);
+
+	fmt.pad = source_pad->index;
+	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
+			       pad, get_fmt, NULL, &fmt);
+	BUG_ON(ret < 0);

That's a bit harsh. I'd rather return an error.

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 984

Quoted 3 lines
drivers/media/video/omap3isp/ispvideo.c +3 -0
+
+	pipe->external_bpp = omap3isp_video_format_info(
+		fmt.format.code)->bpp;

Maybe you could teachs emacs that 78 characters fit in a 80-columns line ? :-)

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 991

Quoted 7 lines
drivers/media/video/omap3isp/ispvideo.c +7 -0
+
+	memset(&ctrls, 0, sizeof(ctrls));
+	memset(&ctrl, 0, sizeof(ctrl));
+
+	ctrl.id = V4L2_CID_PIXEL_RATE;
+
+	ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(ctrl.id);

You can leave ctrl_class to 0.

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 998

Quoted 7 lines
drivers/media/video/omap3isp/ispvideo.c +7 -0
+	ctrls.count = 1;
+	ctrls.controls = &ctrl;
+
+	ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
+	if (ret < 0) {
+		dev_warn(isp->dev,
+			 "no pixel rate control in subdev %s\n",

No need to split this either.

Quoted 23 lines
drivers/media/video/omap3isp/ispvideo.c +13 -0
+			 pipe->external->name);
+		return ret;
+	}
+
+	pipe->external_rate = ctrl.value64;
+
+	return 0;
+}
+
 /*
  * Stream management
  *
@@ -1010,6 +1081,10 @@ isp_video_streamon(struct file *file, void *fh, enum
 v4l2_buf_type type) while ((entity = media_entity_graph_walk_next(&graph)))
 		pipe->entities |= 1 << entity->id;
 
+	ret = isp_video_check_external_subdevs(pipe);
+	if (ret < 0)
+		goto err_check_format;
+
 	/* Verify that the currently configured format matches the output of
 	 * the connected subdev.
 	 */
Signature · 3 lines
Regards,

Laurent Pinchart
#54 lore raw

Re: [PATCH v5 27/35] omap3isp: Introduce isp_video_check_external_subdevs()

Hi Laurent,

Thanks for the comments!

Quoted 19 lines · Laurent Pinchart
Quoted 18 lines · On Tuesday 06 March 2012 18:33:08 Sakari Ailus wrote:

isp_video_check_external_subdevs() will retrieve external subdev's bits-per-pixel and pixel rate for the use of other ISP subdevs at streamon time. isp_video_check_external_subdevs() is called after pipeline validation.

---
 drivers/media/video/omap3isp/ispvideo.c |   75 ++++++++++++++++++++++++++++
 1 files changed, 75 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.c index 4bc9cca..ef5c770 100644

drivers/media/video/omap3isp/ispvideo.c +0 -0
@@ -934,6 +934,77 @@ isp_video_dqbuf(struct file *file, void *fh, struct
 v4l2_buffer *b) file->f_flags & O_NONBLOCK);
 }
 
Quoted 6 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 940

Quoted 4 lines
drivers/media/video/omap3isp/ispvideo.c +4 -0
+static int isp_video_check_external_subdevs(struct isp_pipeline *pipe)
+{
+	struct isp_device *isp =
+		container_of(pipe, struct isp_video, pipe)->isp;

Any reason not to pass isp_device * from the caller to this function ?

I didn't simply because it was unnecessary. Should I? "pipe" is needed in any case.

Quoted 7 lines
Quoted 7 lines
drivers/media/video/omap3isp/ispvideo.c +7 -0
+	struct media_entity *ents[] = {
+		&isp->isp_csi2a.subdev.entity,
+		&isp->isp_csi2c.subdev.entity,
+		&isp->isp_ccp2.subdev.entity,
+		&isp->isp_ccdc.subdev.entity
+	};
+	struct media_pad *source_pad;
Quoted 8 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 953

Quoted 6 lines
drivers/media/video/omap3isp/ispvideo.c +6 -0
+	struct media_entity *source = NULL;
+	struct media_entity *sink;
+	struct v4l2_subdev_format fmt;
+	struct v4l2_ext_controls ctrls;
+	struct v4l2_ext_control ctrl;
+	int i;

i is allowed to be unsigned in this driver as well ;-)

unsigned... we meet again!

Quoted 5 lines
Quoted 5 lines
drivers/media/video/omap3isp/ispvideo.c +5 -0
+	int ret = 0;
+
+	for (i = 0; i < ARRAY_SIZE(ents); i++) {
+		/* Is the entity part of the pipeline? */
+		if (!(pipe->entities & (1 << ents[i]->id)))
Quoted 8 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 963

Quoted 5 lines
drivers/media/video/omap3isp/ispvideo.c +5 -0
+			continue;
+
+		/* ISP entities have always sink pad == 0. Find source. */
+		source_pad = media_entity_remote_source(&ents[i]->pads[0]);
+

Don't you usually avoid blank lines between a variable assignment and checking it for an error condition ?

We do. Fixed.

Quoted 12 lines
Quoted 12 lines
drivers/media/video/omap3isp/ispvideo.c +12 -0
+		if (source_pad == NULL)
+			continue;
+
+		source = source_pad->entity;
+		sink = ents[i];
+		break;
+	}
+
+	if (!source || media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
+		return 0;
+
+	pipe->external = media_entity_to_v4l2_subdev(source);
Quoted 8 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 981

Quoted 6 lines
drivers/media/video/omap3isp/ispvideo.c +6 -0
+
+	fmt.pad = source_pad->index;
+	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
+			       pad, get_fmt, NULL, &fmt);
+	BUG_ON(ret < 0);

That's a bit harsh. I'd rather return an error.

This is a driver BUG(). At the very least it's WARN() and return an error... I think I'll do dev_warn("message") and return the error.

I actually add the same for the case where source is NULL --- that's also a driver bug.

Quoted 5 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 984

Quoted 3 lines
drivers/media/video/omap3isp/ispvideo.c +3 -0
+
+	pipe->external_bpp = omap3isp_video_format_info(
+		fmt.format.code)->bpp;

Maybe you could teachs emacs that 78 characters fit in a 80-columns line ? :-)

That's 79, not 78. And I need to scroll to the end of the line you wrote to see it after it has been prefixed with "> ". :-D

I think I've been renaming things and as a result it did fit on a single line.

Quoted 9 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 991

Quoted 7 lines
drivers/media/video/omap3isp/ispvideo.c +7 -0
+
+	memset(&ctrls, 0, sizeof(ctrls));
+	memset(&ctrl, 0, sizeof(ctrl));
+
+	ctrl.id = V4L2_CID_PIXEL_RATE;
+
+	ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(ctrl.id);

You can leave ctrl_class to 0.

Fixed.

Quoted 9 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 998

Quoted 7 lines
drivers/media/video/omap3isp/ispvideo.c +7 -0
+	ctrls.count = 1;
+	ctrls.controls = &ctrl;
+
+	ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
+	if (ret < 0) {
+		dev_warn(isp->dev,
+			 "no pixel rate control in subdev %s\n",

No need to split this either.

Fixed.

Kind regards,

Signature · 2 lines
Sakari Ailus
e-mail: [email protected]	jabber/XMPP/Gmail: [email protected]
maintainer
#55 lore raw

Re: [PATCH v5 27/35] omap3isp: Introduce isp_video_check_external_subdevs()

Hi Sakari,

Quoted 31 lines · On Wednesday 07 March 2012 19:49:46 Sakari Ailus wrote:
Quoted 21 lines · Laurent Pinchart
Quoted 20 lines · On Tuesday 06 March 2012 18:33:08 Sakari Ailus wrote:

isp_video_check_external_subdevs() will retrieve external subdev's bits-per-pixel and pixel rate for the use of other ISP subdevs at streamon
time. isp_video_check_external_subdevs() is called after pipeline validation.

---

 drivers/media/video/omap3isp/ispvideo.c |   75
 ++++++++++++++++++++++++++++
 1 files changed, 75 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.c index 4bc9cca..ef5c770 100644

drivers/media/video/omap3isp/ispvideo.c +0 -0
@@ -934,6 +934,77 @@ isp_video_dqbuf(struct file *file, void *fh, struct
 v4l2_buffer *b) file->f_flags & O_NONBLOCK);
 
Quoted 8 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 940

Quoted 6 lines
drivers/media/video/omap3isp/ispvideo.c +4 -0
 }
 
+static int isp_video_check_external_subdevs(struct isp_pipeline *pipe)
+{
+	struct isp_device *isp =
+		container_of(pipe, struct isp_video, pipe)->isp;

Any reason not to pass isp_device * from the caller to this function ?

Quoted 2 lines

I didn't simply because it was unnecessary. Should I? "pipe" is needed in any case.

It will look simpler (in my opinion), and will probably generate less code, so I think you should.

Quoted 55 lines
Quoted 7 lines
Quoted 7 lines
drivers/media/video/omap3isp/ispvideo.c +7 -0
+	struct media_entity *ents[] = {
+		&isp->isp_csi2a.subdev.entity,
+		&isp->isp_csi2c.subdev.entity,
+		&isp->isp_ccp2.subdev.entity,
+		&isp->isp_ccdc.subdev.entity
+	};
+	struct media_pad *source_pad;
Quoted 8 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 953

Quoted 6 lines
drivers/media/video/omap3isp/ispvideo.c +6 -0
+	struct media_entity *source = NULL;
+	struct media_entity *sink;
+	struct v4l2_subdev_format fmt;
+	struct v4l2_ext_controls ctrls;
+	struct v4l2_ext_control ctrl;
+	int i;

i is allowed to be unsigned in this driver as well ;-)

unsigned... we meet again!

Quoted 5 lines
Quoted 5 lines
drivers/media/video/omap3isp/ispvideo.c +5 -0
+	int ret = 0;
+
+	for (i = 0; i < ARRAY_SIZE(ents); i++) {
+		/* Is the entity part of the pipeline? */
+		if (!(pipe->entities & (1 << ents[i]->id)))
Quoted 8 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 963

Quoted 5 lines
drivers/media/video/omap3isp/ispvideo.c +5 -0
+			continue;
+
+		/* ISP entities have always sink pad == 0. Find source. */
+		source_pad = media_entity_remote_source(&ents[i]->pads[0]);
+

Don't you usually avoid blank lines between a variable assignment and checking it for an error condition ?

We do. Fixed.

Quoted 12 lines
Quoted 12 lines
drivers/media/video/omap3isp/ispvideo.c +12 -0
+		if (source_pad == NULL)
+			continue;
+
+		source = source_pad->entity;
+		sink = ents[i];
+		break;
+	}
+
+	if (!source || media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
+		return 0;
+
+	pipe->external = media_entity_to_v4l2_subdev(source);
Quoted 8 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 981

Quoted 6 lines
drivers/media/video/omap3isp/ispvideo.c +6 -0
+
+	fmt.pad = source_pad->index;
+	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
+			       pad, get_fmt, NULL, &fmt);
+	BUG_ON(ret < 0);

That's a bit harsh. I'd rather return an error.

Quoted 2 lines

This is a driver BUG(). At the very least it's WARN() and return an error... I think I'll do dev_warn("message") and return the error.

dev_warn + return error sounds good.

Quoted 38 lines

I actually add the same for the case where source is NULL --- that's also a driver bug.

Quoted 6 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 984

Quoted 3 lines
drivers/media/video/omap3isp/ispvideo.c +3 -0
+
+	pipe->external_bpp = omap3isp_video_format_info(
+		fmt.format.code)->bpp;

Maybe you could teachs emacs that 78 characters fit in a 80-columns line ? :-)

That's 79, not 78. And I need to scroll to the end of the line you wrote to see it after it has been prefixed with "> ". :-D

I think I've been renaming things and as a result it did fit on a single line.

Quoted 9 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 991

Quoted 7 lines
drivers/media/video/omap3isp/ispvideo.c +7 -0
+
+	memset(&ctrls, 0, sizeof(ctrls));
+	memset(&ctrl, 0, sizeof(ctrl));
+
+	ctrl.id = V4L2_CID_PIXEL_RATE;
+
+	ctrls.ctrl_class = V4L2_CTRL_ID2CLASS(ctrl.id);

You can leave ctrl_class to 0.

Fixed.

Quoted 9 lines

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) · line 998

Quoted 7 lines
drivers/media/video/omap3isp/ispvideo.c +7 -0
+	ctrls.count = 1;
+	ctrls.controls = &ctrl;
+
+	ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
+	if (ret < 0) {
+		dev_warn(isp->dev,
+			 "no pixel rate control in subdev %s\n",

No need to split this either.

Fixed.

Signature · 3 lines
Regards,

Laurent Pinchart
#56 lore raw

Re: [PATCH v5 27/35] omap3isp: Introduce isp_video_check_external_subdevs()

Hi Laurent,

Quoted 32 lines · Laurent Pinchart
Quoted 31 lines · On Wednesday 07 March 2012 19:49:46 Sakari Ailus wrote:
Quoted 29 lines · Laurent Pinchart
Quoted 18 lines · On Tuesday 06 March 2012 18:33:08 Sakari Ailus wrote:

isp_video_check_external_subdevs() will retrieve external subdev's bits-per-pixel and pixel rate for the use of other ISP subdevs at streamon
time. isp_video_check_external_subdevs() is called after pipeline validation.

---

  drivers/media/video/omap3isp/ispvideo.c |   75
  ++++++++++++++++++++++++++++
  1 files changed, 75 insertions(+), 0 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.c index 4bc9cca..ef5c770 100644

drivers/media/video/omap3isp/ispvideo.c isp_video_dqbuf(struct file *file, void *fh, struct · line 941

Quoted 8 lines
drivers/media/video/omap3isp/ispvideo.c +4 -0
@@ -934,6 +934,77 @@ isp_video_dqbuf(struct file *file, void *fh, struct
 v4l2_buffer *b) file->f_flags&  O_NONBLOCK);
 
  }
 
+static int isp_video_check_external_subdevs(struct isp_pipeline *pipe)
+{
+	struct isp_device *isp =
+		container_of(pipe, struct isp_video, pipe)->isp;

Any reason not to pass isp_device * from the caller to this function ?

Quoted 5 lines
Quoted 2 lines

I didn't simply because it was unnecessary. Should I? "pipe" is needed in any case.

It will look simpler (in my opinion), and will probably generate less code, so I think you should.

I'll change that for a new version tomorrow.

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

PATCH v5 27/35 omap3isp: Introduce isp_video_check_external_subdevs()

In reply to Laurent Pinchart

isp_video_check_external_subdevs() will retrieve external subdev's bits-per-pixel and pixel rate for the use of other ISP subdevs at streamon time. isp_video_check_external_subdevs() is called after pipeline validation.

---
 drivers/media/video/omap3isp/ispvideo.c |   79 +++++++++++++++++++++++++++++++
 1 files changed, 79 insertions(+), 0 deletions(-)
drivers/media/video/omap3isp/ispvideo.c +79 -0
index 7411076..c0286c8 100644
@@ -951,6 +951,81 @@ isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
 					  file->f_flags & O_NONBLOCK);
 }
 
+static int isp_video_check_external_subdevs(struct isp_video *video,
+					    struct isp_pipeline *pipe)
+{
+	struct isp_device *isp = video->isp;
+	struct media_entity *ents[] = {
+		&isp->isp_csi2a.subdev.entity,
+		&isp->isp_csi2c.subdev.entity,
+		&isp->isp_ccp2.subdev.entity,
+		&isp->isp_ccdc.subdev.entity
+	};
+	struct media_pad *source_pad;
+	struct media_entity *source = NULL;
+	struct media_entity *sink;
+	struct v4l2_subdev_format fmt;
+	struct v4l2_ext_controls ctrls;
+	struct v4l2_ext_control ctrl;
+	unsigned int i;
+	int ret = 0;
+
+	for (i = 0; i < ARRAY_SIZE(ents); i++) {
+		/* Is the entity part of the pipeline? */
+		if (!(pipe->entities & (1 << ents[i]->id)))
+			continue;
+
+		/* ISP entities have always sink pad == 0. Find source. */
+		source_pad = media_entity_remote_source(&ents[i]->pads[0]);
+		if (source_pad == NULL)
+			continue;
+
+		source = source_pad->entity;
+		sink = ents[i];
+		break;
+	}
+
+	if (!source) {
+		dev_warn(isp->dev, "can't find source, failing now\n");
+		return ret;
+	}
+
+	if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
+		return 0;
+
+	pipe->external = media_entity_to_v4l2_subdev(source);
+
+	fmt.pad = source_pad->index;
+	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
+			       pad, get_fmt, NULL, &fmt);
+	if (unlikely(ret < 0)) {
+		dev_warn(isp->dev, "get_fmt returned null!\n");
+		return ret;
+	}
+
+	pipe->external_bpp = omap3isp_video_format_info(fmt.format.code)->bpp;
+
+	memset(&ctrls, 0, sizeof(ctrls));
+	memset(&ctrl, 0, sizeof(ctrl));
+
+	ctrl.id = V4L2_CID_PIXEL_RATE;
+
+	ctrls.count = 1;
+	ctrls.controls = &ctrl;
+
+	ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
+	if (ret < 0) {
+		dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
+			 pipe->external->name);
+		return ret;
+	}
+
+	pipe->external_rate = ctrl.value64;
+
+	return 0;
+}
+
 /*
  * Stream management
  *
@@ -1033,6 +1108,10 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	if (ret < 0)
 		goto err_check_format;
 
+	ret = isp_video_check_external_subdevs(video, pipe);
+	if (ret < 0)
+		goto err_check_format;
+
 	/* Validate the pipeline and update its state. */
 	ret = isp_video_validate_pipeline(pipe);
 	if (ret < 0)
Signature · 1 line
1.7.2.5
maintainer Acked-by on v5 27/35
#58 lore raw

Re: [PATCH v5.3 27/35] omap3isp: Introduce isp_video_check_external_subdevs()

Hi Sakari,

Thanks for the patch.

Quoted 6 lines · On Thursday 08 March 2012 19:04:24 Sakari Ailus wrote:

isp_video_check_external_subdevs() will retrieve external subdev's bits-per-pixel and pixel rate for the use of other ISP subdevs at streamon time. isp_video_check_external_subdevs() is called after pipeline validation.

Signature · 3 lines
Regards,

Laurent Pinchart
#59 lore raw

PATCH v5 27/35 omap3isp: Introduce isp_video_check_external_subdevs()

In reply to Laurent Pinchart

isp_video_check_external_subdevs() will retrieve external subdev's bits-per-pixel and pixel rate for the use of other ISP subdevs at streamon time. isp_video_check_external_subdevs() is called after pipeline validation.

---
 drivers/media/video/omap3isp/ispvideo.c |   79 +++++++++++++++++++++++++++++++
 1 files changed, 79 insertions(+), 0 deletions(-)
drivers/media/video/omap3isp/ispvideo.c +79 -0
index 7411076..f3b82cae4 100644
@@ -951,6 +951,81 @@ isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
 					  file->f_flags & O_NONBLOCK);
 }
 
+static int isp_video_check_external_subdevs(struct isp_pipeline *pipe)
+{
+	struct isp_device *isp =
+		container_of(pipe, struct isp_video, pipe)->isp;
+	struct media_entity *ents[] = {
+		&isp->isp_csi2a.subdev.entity,
+		&isp->isp_csi2c.subdev.entity,
+		&isp->isp_ccp2.subdev.entity,
+		&isp->isp_ccdc.subdev.entity
+	};
+	struct media_pad *source_pad;
+	struct media_entity *source = NULL;
+	struct media_entity *sink;
+	struct v4l2_subdev_format fmt;
+	struct v4l2_ext_controls ctrls;
+	struct v4l2_ext_control ctrl;
+	unsigned int i;
+	int ret = 0;
+
+	for (i = 0; i < ARRAY_SIZE(ents); i++) {
+		/* Is the entity part of the pipeline? */
+		if (!(pipe->entities & (1 << ents[i]->id)))
+			continue;
+
+		/* ISP entities have always sink pad == 0. Find source. */
+		source_pad = media_entity_remote_source(&ents[i]->pads[0]);
+		if (source_pad == NULL)
+			continue;
+
+		source = source_pad->entity;
+		sink = ents[i];
+		break;
+	}
+
+	if (!source) {
+		dev_warn(isp->dev, "can't find source, failing now\n");
+		return ret;
+	}
+
+	if (media_entity_type(source) != MEDIA_ENT_T_V4L2_SUBDEV)
+		return 0;
+
+	pipe->external = media_entity_to_v4l2_subdev(source);
+
+	fmt.pad = source_pad->index;
+	fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+	ret = v4l2_subdev_call(media_entity_to_v4l2_subdev(sink),
+			       pad, get_fmt, NULL, &fmt);
+	if (unlikely(ret < 0)) {
+		dev_warn(isp->dev, "get_fmt returned null!\n");
+		return ret;
+	}
+
+	pipe->external_bpp = omap3isp_video_format_info(fmt.format.code)->bpp;
+
+	memset(&ctrls, 0, sizeof(ctrls));
+	memset(&ctrl, 0, sizeof(ctrl));
+
+	ctrl.id = V4L2_CID_PIXEL_RATE;
+
+	ctrls.count = 1;
+	ctrls.controls = &ctrl;
+
+	ret = v4l2_g_ext_ctrls(pipe->external->ctrl_handler, &ctrls);
+	if (ret < 0) {
+		dev_warn(isp->dev, "no pixel rate control in subdev %s\n",
+			 pipe->external->name);
+		return ret;
+	}
+
+	pipe->external_rate = ctrl.value64;
+
+	return 0;
+}
+
 /*
  * Stream management
  *
@@ -1033,6 +1108,10 @@ isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
 	if (ret < 0)
 		goto err_check_format;
 
+	ret = isp_video_check_external_subdevs(pipe);
+	if (ret < 0)
+		goto err_check_format;
+
 	/* Validate the pipeline and update its state. */
 	ret = isp_video_validate_pipeline(pipe);
 	if (ret < 0)
Signature · 1 line
1.7.2.5
#60 lore raw

PATCH v5 28/35 omap3isp: Use external rate instead of vpcfg

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

Access pipe->external_rate instead of isp_ccdc.vpcfg.pixelclk. Also remove means to set the value for isp_ccdc_vpcfg.pixelclk.

---
 drivers/media/video/omap3isp/isp.c      |   14 --------------
 drivers/media/video/omap3isp/isp.h      |    1 -
 drivers/media/video/omap3isp/ispccdc.c  |    6 ++----
 drivers/media/video/omap3isp/ispccdc.h  |   10 ----------
 drivers/media/video/omap3isp/ispvideo.c |    2 +-
 5 files changed, 3 insertions(+), 30 deletions(-)
drivers/media/video/omap3isp/isp.c +0 -14
index 12d5f92..f54953d 100644
@@ -329,19 +329,6 @@ void omap3isp_configure_bridge(struct isp_device *isp,
 	isp_reg_writel(isp, ispctrl_val, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
 }
 
-/**
- * isp_set_pixel_clock - Configures the ISP pixel clock
- * @isp: OMAP3 ISP device
- * @pixelclk: Average pixel clock in Hz
- *
- * Set the average pixel clock required by the sensor. The ISP will use the
- * lowest possible memory bandwidth settings compatible with the clock.
- **/
-static void isp_set_pixel_clock(struct isp_device *isp, unsigned int pixelclk)
-{
-	isp->isp_ccdc.vpcfg.pixelclk = pixelclk;
-}
-
 void omap3isp_hist_dma_done(struct isp_device *isp)
 {
 	if (omap3isp_ccdc_busy(&isp->isp_ccdc) ||
@@ -2068,7 +2055,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 2e78041..964ab1b 100644
@@ -129,7 +129,6 @@ struct isp_platform_callback {
 	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/ispccdc.c +2 -4
index a74a797..cd1bf6d 100644
@@ -836,8 +836,8 @@ static void ccdc_config_vp(struct isp_ccdc_device *ccdc)
 
 	if (pipe->input)
 		div = DIV_ROUND_UP(l3_ick, pipe->max_rate);
-	else if (ccdc->vpcfg.pixelclk)
-		div = l3_ick / ccdc->vpcfg.pixelclk;
+	else if (pipe->external_rate)
+		div = l3_ick / pipe->external_rate;
 
 	div = clamp(div, 2U, max_div);
 	fmtcfg_vp |= (div - 2) << ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT;
@@ -2276,8 +2276,6 @@ int omap3isp_ccdc_init(struct isp_device *isp)
 	ccdc->clamp.oblen = 0;
 	ccdc->clamp.dcsubval = 0;
 
-	ccdc->vpcfg.pixelclk = 0;
-
 	ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
 	ccdc_apply_controls(ccdc);
 
drivers/media/video/omap3isp/ispccdc.h +0 -10
index 6d0264b..e570abe 100644
@@ -80,14 +80,6 @@ struct ispccdc_syncif {
 	u8 bt_r656_en;
 };
 
-/*
- * struct ispccdc_vp - Structure for Video Port parameters
- * @pixelclk: Input pixel clock in Hz
- */
-struct ispccdc_vp {
-	unsigned int pixelclk;
-};
-
 enum ispccdc_lsc_state {
 	LSC_STATE_STOPPED = 0,
 	LSC_STATE_STOPPING = 1,
@@ -161,7 +153,6 @@ struct ispccdc_lsc {
  * @update: Bitmask of controls to update during the next interrupt
  * @shadow_update: Controls update in progress by userspace
  * @syncif: Interface synchronization configuration
- * @vpcfg: Video port configuration
  * @underrun: A buffer underrun occurred and a new buffer has been queued
  * @state: Streaming state
  * @lock: Serializes shadow_update with interrupt handler
@@ -190,7 +181,6 @@ struct isp_ccdc_device {
 	unsigned int shadow_update;
 
 	struct ispccdc_syncif syncif;
-	struct ispccdc_vp vpcfg;
 
 	unsigned int underrun:1;
 	enum isp_pipeline_stream_state state;
drivers/media/video/omap3isp/ispvideo.c +1 -1
index ef5c770..6d4ad87 100644
@@ -334,7 +334,7 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
 			unsigned int rate = UINT_MAX;
 
 			omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
-			if (isp->isp_ccdc.vpcfg.pixelclk > rate)
+			if (pipe->external_rate > rate)
 				return -ENOSPC;
 		}
 
Signature · 1 line
1.7.2.5
maintainer Acked-by on v5 28/35
#61 lore raw

Re: [PATCH v5 28/35] omap3isp: Use external rate instead of vpcfg

Hi Sakari,

Thanks for the patch.

Quoted 6 lines · On Tuesday 06 March 2012 18:33:09 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Access pipe->external_rate instead of isp_ccdc.vpcfg.pixelclk. Also remove means to set the value for isp_ccdc_vpcfg.pixelclk.

Very nice.

This also means that implementing support for the V4L2_CID_PIXEL_RATE control is required in the sensor drivers to be used with the OMAP3 ISP. I'll submit patches.

Signature · 3 lines
Regards,

Laurent Pinchart
#62 lore raw

Re: [PATCH v5 28/35] omap3isp: Use external rate instead of vpcfg

Quoted 12 lines · Laurent Pinchart

Hi Sakari,

Thanks for the patch.

Quoted 6 lines · On Tuesday 06 March 2012 18:33:09 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Access pipe->external_rate instead of isp_ccdc.vpcfg.pixelclk. Also remove means to set the value for isp_ccdc_vpcfg.pixelclk.

Quoted 7 lines

Very nice.

This also means that implementing support for the V4L2_CID_PIXEL_RATE control is required in the sensor drivers to be used with the OMAP3 ISP. I'll submit patches.

Thanks!

Let's see how we deal with the affected drivers...

Signature · 2 lines
Sakari Ailus
e-mail: [email protected]	jabber/XMPP/Gmail: [email protected]
#63 lore raw

Re: [PATCH v5 28/35] omap3isp: Use external rate instead of vpcfg

In reply to Laurent Pinchart
Quoted 12 lines · Laurent Pinchart

Hi Sakari,

Thanks for the patch.

Quoted 6 lines · On Tuesday 06 March 2012 18:33:09 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Access pipe->external_rate instead of isp_ccdc.vpcfg.pixelclk. Also remove means to set the value for isp_ccdc_vpcfg.pixelclk.

Quoted 7 lines

Very nice.

This also means that implementing support for the V4L2_CID_PIXEL_RATE control is required in the sensor drivers to be used with the OMAP3 ISP. I'll submit patches.

My tree is here if you wish to try it:

<URL:http://git.linuxtv.org/sailus/media_tree.git/shortlog/refs/heads/media-for-3.4>

Cheers,

Signature · 2 lines
Sakari Ailus
e-mail: [email protected]	jabber/XMPP/Gmail: [email protected]
#64 lore raw

PATCH v5 29/35 omap3isp: Default link validation for ccp2, csi2, preview and resizer

In reply to Sakari Ailus

Use default link validation for ccp2, csi2, preview and resizer. On ccp2, csi2 and ccdc we also collect information on external subdevs as one may be connected to those entities.

---
 drivers/media/video/omap3isp/ispccp2.c    |    1 +
 drivers/media/video/omap3isp/ispcsi2.c    |    1 +
 drivers/media/video/omap3isp/isppreview.c |    1 +
 drivers/media/video/omap3isp/ispresizer.c |    1 +
 4 files changed, 4 insertions(+), 0 deletions(-)
drivers/media/video/omap3isp/ispccp2.c +1 -0
index 70ddbf3..41e807f 100644
@@ -1021,6 +1021,7 @@ static int ccp2_link_setup(struct media_entity *entity,
 /* media operations */
 static const struct media_entity_operations ccp2_media_ops = {
 	.link_setup = ccp2_link_setup,
+	.link_validate = v4l2_subdev_link_validate,
 };
 
 /*
drivers/media/video/omap3isp/ispcsi2.c +1 -0
index fcb5168..d2e1c92 100644
@@ -1181,6 +1181,7 @@ static int csi2_link_setup(struct media_entity *entity,
 /* media operations */
 static const struct media_entity_operations csi2_media_ops = {
 	.link_setup = csi2_link_setup,
+	.link_validate = v4l2_subdev_link_validate,
 };
 
 void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2)
drivers/media/video/omap3isp/isppreview.c +1 -0
index 6d0fb2c..8545f0b 100644
@@ -2076,6 +2076,7 @@ static int preview_link_setup(struct media_entity *entity,
 /* media operations */
 static const struct media_entity_operations preview_media_ops = {
 	.link_setup = preview_link_setup,
+	.link_validate = v4l2_subdev_link_validate,
 };
 
 void omap3isp_preview_unregister_entities(struct isp_prev_device *prev)
drivers/media/video/omap3isp/ispresizer.c +1 -0
index 6958a9e..0fc6525 100644
@@ -1603,6 +1603,7 @@ static int resizer_link_setup(struct media_entity *entity,
 /* media operations */
 static const struct media_entity_operations resizer_media_ops = {
 	.link_setup = resizer_link_setup,
+	.link_validate = v4l2_subdev_link_validate,
 };
 
 void omap3isp_resizer_unregister_entities(struct isp_res_device *res)
Signature · 1 line
1.7.2.5
#65 lore raw

PATCH v5 30/35 omap3isp: Move CCDC link validation to ccdc_link_validate()

In reply to Sakari Ailus

Perform CCDC link validation in ccdc_link_validate() instead of isp_video_validate_pipeline(). Also perform maximum data rate check in isp_video_check_external_subdevs().

---
 drivers/media/video/omap3isp/ispccdc.c  |   65 +++++++++++++++++++++
 drivers/media/video/omap3isp/ispvideo.c |   94 ++++---------------------------
 2 files changed, 76 insertions(+), 83 deletions(-)
drivers/media/video/omap3isp/ispccdc.c +65 -0
index cd1bf6d..84f230e 100644
@@ -2000,6 +2000,69 @@ static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
 }
 
 /*
+ * Decide whether desired output pixel code can be obtained with
+ * the lane shifter by shifting the input pixel code.
+ * @in: input pixelcode to shifter
+ * @out: output pixelcode from shifter
+ * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0]
+ *
+ * return true if the combination is possible
+ * return false otherwise
+ */
+static bool ccdc_is_shiftable(enum v4l2_mbus_pixelcode in,
+			      enum v4l2_mbus_pixelcode out,
+			      unsigned int additional_shift)
+{
+	const struct isp_format_info *in_info, *out_info;
+
+	if (in == out)
+		return true;
+
+	in_info = omap3isp_video_format_info(in);
+	out_info = omap3isp_video_format_info(out);
+
+	if ((in_info->flavor == 0) || (out_info->flavor == 0))
+		return false;
+
+	if (in_info->flavor != out_info->flavor)
+		return false;
+
+	return in_info->bpp - out_info->bpp + additional_shift <= 6;
+}
+
+static int ccdc_link_validate(struct v4l2_subdev *sd,
+			      struct media_link *link,
+			      struct v4l2_subdev_format *source_fmt,
+			      struct v4l2_subdev_format *sink_fmt)
+{
+	struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
+	unsigned long parallel_shift;
+
+	/* Check if the two ends match */
+	if (source_fmt->format.width != sink_fmt->format.width ||
+	    source_fmt->format.height != sink_fmt->format.height)
+		return -EPIPE;
+
+	/* We've got a parallel sensor here. */
+	if (ccdc->input == CCDC_INPUT_PARALLEL) {
+		struct isp_parallel_platform_data *pdata =
+			&((struct isp_v4l2_subdevs_group *)
+			  media_entity_to_v4l2_subdev(link->source->entity)
+			  ->host_priv)->bus.parallel;
+		parallel_shift = pdata->data_lane_shift * 2;
+	} else {
+		parallel_shift = 0;
+	}
+
+	/* Lane shifter may be used to drop bits on CCDC sink pad */
+	if (!ccdc_is_shiftable(source_fmt->format.code,
+			       sink_fmt->format.code, parallel_shift))
+		return -EPIPE;
+
+	return 0;
+}
+
+/*
  * ccdc_init_formats - Initialize formats on all pads
  * @sd: ISP CCDC V4L2 subdevice
  * @fh: V4L2 subdev file handle
@@ -2041,6 +2104,7 @@ static const struct v4l2_subdev_pad_ops ccdc_v4l2_pad_ops = {
 	.enum_frame_size = ccdc_enum_frame_size,
 	.get_fmt = ccdc_get_format,
 	.set_fmt = ccdc_set_format,
+	.link_validate = ccdc_link_validate,
 };
 
 /* V4L2 subdev operations */
@@ -2150,6 +2214,7 @@ static int ccdc_link_setup(struct media_entity *entity,
 /* media operations */
 static const struct media_entity_operations ccdc_media_ops = {
 	.link_setup = ccdc_link_setup,
+	.link_validate = v4l2_subdev_link_validate,
 };
 
 void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
drivers/media/video/omap3isp/ispvideo.c +11 -83

142 lines not on this page · raw message

Signature · 1 line
1.7.2.5
maintainer Acked-by on v5 30/35
#66 lore raw

Re: [PATCH v5 30/35] omap3isp: Move CCDC link validation to ccdc_link_validate()

Hi Sakari,

Thanks for the patch.

Quoted 5 lines · On Tuesday 06 March 2012 18:33:11 Sakari Ailus wrote:

Perform CCDC link validation in ccdc_link_validate() instead of isp_video_validate_pipeline(). Also perform maximum data rate check in isp_video_check_external_subdevs().

[snip]

Quoted 4 lines
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.c index 6d4ad87..51075b3 100644

drivers/media/video/omap3isp/ispvideo.c +0 -0

[snip]

drivers/media/video/omap3isp/ispvideo.c static int isp_video_check_external_subdevs(struct · line 870

Quoted 5 lines
drivers/media/video/omap3isp/ispvideo.c +1 -0
@@ -950,6 +867,7 @@ static int isp_video_check_external_subdevs(struct
 isp_pipeline *pipe) struct v4l2_subdev_format fmt;
 	struct v4l2_ext_controls ctrls;
 	struct v4l2_ext_control ctrl;
+	unsigned int rate = UINT_MAX;

You can move this variable inside the if statement below.

drivers/media/video/omap3isp/ispvideo.c static int isp_video_check_external_subdevs(struct · line 927

Quoted 12 lines
drivers/media/video/omap3isp/ispvideo.c +4 -0
 	int i;
 	int ret = 0;
 
@@ -1002,6 +920,16 @@ static int isp_video_check_external_subdevs(struct
 isp_pipeline *pipe)
 
 	pipe->external_rate = ctrl.value64;
 
+	if (pipe->entities & (1 << isp->isp_ccdc.subdev.entity.id)) {
+		/*
+		 * Check that maximum allowed CCDC pixel rate isn't
+		 * exceeded by the pixel rate.

What's wrong with 80 columns, really ? :-)

drivers/media/video/omap3isp/ispvideo.c static int isp_video_check_external_subdevs(struct isp_pipeline *pipe) · line 934

Quoted 8 lines
drivers/media/video/omap3isp/ispvideo.c +6 -0
+		 */
+		omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
+		if (pipe->external_rate > rate)
+			return -ENOSPC;
+	}
+
 	return 0;
 }

Pending those two changes,

Signature · 3 lines
Regards,

Laurent Pinchart
#67 lore raw

Re: [PATCH v5 30/35] omap3isp: Move CCDC link validation to ccdc_link_validate()

Hi Laurent,

Thanks for the comments.

Quoted 16 lines · Laurent Pinchart
Quoted 5 lines · On Tuesday 06 March 2012 18:33:11 Sakari Ailus wrote:

Perform CCDC link validation in ccdc_link_validate() instead of isp_video_validate_pipeline(). Also perform maximum data rate check in isp_video_check_external_subdevs().

[snip]

Quoted 4 lines
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/ispvideo.c index 6d4ad87..51075b3 100644

drivers/media/video/omap3isp/ispvideo.c +0 -0

[snip]

Quoted 7 lines

drivers/media/video/omap3isp/ispvideo.c static int isp_video_check_external_subdevs(struct · line 870

Quoted 5 lines
drivers/media/video/omap3isp/ispvideo.c +1 -0
@@ -950,6 +867,7 @@ static int isp_video_check_external_subdevs(struct
 isp_pipeline *pipe) struct v4l2_subdev_format fmt;
 	struct v4l2_ext_controls ctrls;
 	struct v4l2_ext_control ctrl;
+	unsigned int rate = UINT_MAX;

You can move this variable inside the if statement below.

Fixed.

Quoted 6 lines
Quoted 6 lines
drivers/media/video/omap3isp/ispvideo.c +0 -0
 	int i;
 	int ret = 0;
 
@@ -1002,6 +920,16 @@ static int isp_video_check_external_subdevs(struct
 isp_pipeline *pipe)
 
Quoted 8 lines

drivers/media/video/omap3isp/ispvideo.c static int isp_video_check_external_subdevs(struct isp_pipeline *pipe) · line 926

Quoted 6 lines
drivers/media/video/omap3isp/ispvideo.c +4 -0
 	pipe->external_rate = ctrl.value64;
 
+	if (pipe->entities & (1 << isp->isp_ccdc.subdev.entity.id)) {
+		/*
+		 * Check that maximum allowed CCDC pixel rate isn't
+		 * exceeded by the pixel rate.

What's wrong with 80 columns, really ? :-)

Is it said somewhere in CodingStyle the comments have to be wrapped at 80 characters and no earlier? It's like speed limits: you are allowed to drive slower than the limit. :-)

Quoted 11 lines

drivers/media/video/omap3isp/ispvideo.c static int isp_video_check_external_subdevs(struct isp_pipeline *pipe) · line 934

Quoted 8 lines
drivers/media/video/omap3isp/ispvideo.c +6 -0
+		 */
+		omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
+		if (pipe->external_rate > rate)
+			return -ENOSPC;
+	}
+
 	return 0;
 }

Pending those two changes,

Quoted 1 line

Thanks. :-)

Cheers,

Signature · 2 lines
Sakari Ailus
e-mail: [email protected]	jabber/XMPP/Gmail: [email protected]
#68 lore raw

PATCH v5 31/35 omap3isp: Configure CSI-2 phy based on platform data

In reply to Sakari Ailus

Configure CSI-2 phy based on platform data in the ISP driver. For that, the new V4L2_CID_IMAGE_SOURCE_PIXEL_RATE control is used. Previously the same was configured from the board code.

---
 drivers/media/video/omap3isp/isp.h       |    3 -
 drivers/media/video/omap3isp/ispcsiphy.c |  168 +++++++++++++++++-------------
 drivers/media/video/omap3isp/ispcsiphy.h |   10 --
 3 files changed, 97 insertions(+), 84 deletions(-)
drivers/media/video/omap3isp/isp.h +0 -3
index 964ab1b..7533a40 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);
 };
 
 /*
drivers/media/video/omap3isp/ispcsiphy.c +97 -71

210 lines not on this page · raw message

drivers/media/video/omap3isp/ispcsiphy.h +0 -10
index e93a661..14551fd 100644
@@ -32,14 +32,6 @@
 struct isp_csi2_device;
 struct regulator;
 
-struct isp_csiphy_dphy_cfg {
-	u8 ths_term;
-	u8 ths_settle;
-	u8 tclk_term;
-	unsigned tclk_miss:1;
-	u8 tclk_settle;
-};
-
 struct isp_csiphy {
 	struct isp_device *isp;
 	struct mutex mutex;	/* serialize csiphy configuration */
@@ -52,8 +44,6 @@ struct isp_csiphy {
 	unsigned int phy_regs;
 
 	u8 num_data_lanes;	/* number of CSI2 Data Lanes supported */
-	struct isp_csiphy_lanes_cfg lanes;
-	struct isp_csiphy_dphy_cfg dphy;
 };
 
 int omap3isp_csiphy_acquire(struct isp_csiphy *phy);
Signature · 1 line
1.7.2.5
#69 lore raw

PATCH v5 32/35 omap3isp: Add resizer data rate configuration to resizer_link_validate

In reply to Sakari Ailus

The configuration of many other blocks depend on resizer maximum data rate. Get the value from resizer at link validation time.

---
 drivers/media/video/omap3isp/ispresizer.c |   15 ++++++++
 drivers/media/video/omap3isp/ispvideo.c   |   54 -----------------------------
 2 files changed, 15 insertions(+), 54 deletions(-)
drivers/media/video/omap3isp/ispresizer.c +15 -0
index 0fc6525..dda49cb 100644
@@ -1494,6 +1494,20 @@ static int resizer_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
 	return 0;
 }
 
+static int resizer_link_validate(struct v4l2_subdev *sd,
+				 struct media_link *link,
+				 struct v4l2_subdev_format *source_fmt,
+				 struct v4l2_subdev_format *sink_fmt)
+{
+	struct isp_res_device *res = v4l2_get_subdevdata(sd);
+	struct isp_pipeline *pipe = to_isp_pipeline(&sd->entity);
+
+	omap3isp_resizer_max_rate(res, &pipe->max_rate);
+
+	return v4l2_subdev_link_validate_default(sd, link,
+						 source_fmt, sink_fmt);
+}
+
 /*
  * resizer_init_formats - Initialize formats on all pads
  * @sd: ISP resizer V4L2 subdevice
@@ -1532,6 +1546,7 @@ static const struct v4l2_subdev_pad_ops resizer_v4l2_pad_ops = {
 	.set_fmt = resizer_set_format,
 	.get_crop = resizer_g_crop,
 	.set_crop = resizer_s_crop,
+	.link_validate = resizer_link_validate,
 };
 
 /* subdev operations */
drivers/media/video/omap3isp/ispvideo.c +0 -54

66 lines not on this page · raw message

Signature · 1 line
1.7.2.5
maintainer Acked-by on v5 32/35
#70 lore raw

Re: [PATCH v5 32/35] omap3isp: Add resizer data rate configuration to resizer_link_validate

Hi Sakari,

Thanks for the patch.

Quoted 4 lines · On Tuesday 06 March 2012 18:33:13 Sakari Ailus wrote:

The configuration of many other blocks depend on resizer maximum data rate. Get the value from resizer at link validation time.

Signature · 3 lines
Regards,

Laurent Pinchart
#71 lore raw

PATCH v5 33/35 omap3isp: Find source pad from external entity

In reply to Sakari Ailus

No longer assume pad number 0 is the source pad of the external entity. Find the source pad from the external entity and use it instead.

---
 drivers/media/video/omap3isp/isp.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)
drivers/media/video/omap3isp/isp.c +12 -1
index f54953d..0718b0a 100644
@@ -1744,6 +1744,7 @@ static int isp_register_entities(struct isp_device *isp)
 		struct media_entity *input;
 		unsigned int flags;
 		unsigned int pad;
+		unsigned int i;
 
 		sensor = isp_register_subdev_group(isp, subdevs->subdevs);
 		if (sensor == NULL)
@@ -1791,7 +1792,17 @@ static int isp_register_entities(struct isp_device *isp)
 			goto done;
 		}
 
-		ret = media_entity_create_link(&sensor->entity, 0, input, pad,
+		for (i = 0; i < sensor->entity.num_pads; i++)
+			if (sensor->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
+				break;
+		if (i == sensor->entity.num_pads) {
+			dev_err(isp->dev,
+				"no source pads in external entities\n");
+			ret = -EINVAL;
+			goto done;
+		}
+
+		ret = media_entity_create_link(&sensor->entity, i, input, pad,
 					       flags);
 		if (ret < 0)
 			goto done;
Signature · 1 line
1.7.2.5
maintainer Acked-by on v5 33/35
#72 lore raw

Re: [PATCH v5 33/35] omap3isp: Find source pad from external entity

Hi Sakari,

Thanks for the patch.

Quoted 4 lines · On Tuesday 06 March 2012 18:33:14 Sakari Ailus wrote:

No longer assume pad number 0 is the source pad of the external entity. Find the source pad from the external entity and use it instead.

(with one comment below)

Quoted 17 lines
---
 drivers/media/video/omap3isp/isp.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/isp.c index f54953d..0718b0a 100644

drivers/media/video/omap3isp/isp.c +1 -0
@@ -1744,6 +1744,7 @@ static int isp_register_entities(struct isp_device
 *isp) struct media_entity *input;
 		unsigned int flags;
 		unsigned int pad;
+		unsigned int i;
 
 		sensor = isp_register_subdev_group(isp, subdevs->subdevs);
 		if (sensor == NULL)

drivers/media/video/omap3isp/isp.c static int isp_register_entities(struct isp_device · line 1797

Quoted 7 lines
drivers/media/video/omap3isp/isp.c +3 -1
@@ -1791,7 +1792,17 @@ static int isp_register_entities(struct isp_device
 *isp) goto done;
 		}
 
-		ret = media_entity_create_link(&sensor->entity, 0, input, pad,
+		for (i = 0; i < sensor->entity.num_pads; i++)
+			if (sensor->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
+				break;

While not strictly needed, I find the code easier to read with brackets for the for statement. It's up to you though.

Quoted 11 lines
drivers/media/video/omap3isp/isp.c +8 -0
+		if (i == sensor->entity.num_pads) {
+			dev_err(isp->dev,
+				"no source pads in external entities\n");
+			ret = -EINVAL;
+			goto done;
+		}
+
+		ret = media_entity_create_link(&sensor->entity, i, input, pad,
 					       flags);
 		if (ret < 0)
 			goto done;
Signature · 3 lines
Regards,

Laurent Pinchart
#73 lore raw

Re: [PATCH v5 33/35] omap3isp: Find source pad from external entity

Hi Laurent,

Thanks for the review!!

Quoted 30 lines · Laurent Pinchart
Quoted 4 lines · On Tuesday 06 March 2012 18:33:14 Sakari Ailus wrote:

No longer assume pad number 0 is the source pad of the external entity. Find the source pad from the external entity and use it instead.

(with one comment below)

Quoted 20 lines
---
 drivers/media/video/omap3isp/isp.c |   13 ++++++++++++-
 1 files changed, 12 insertions(+), 1 deletions(-)
(quoted diff) +0 -0

b/drivers/media/video/omap3isp/isp.c index f54953d..0718b0a 100644

drivers/media/video/omap3isp/isp.c +1 -0
@@ -1744,6 +1744,7 @@ static int isp_register_entities(struct isp_device
 *isp) struct media_entity *input;
 		unsigned int flags;
 		unsigned int pad;
+		unsigned int i;
 
 		sensor = isp_register_subdev_group(isp, subdevs->subdevs);
 		if (sensor == NULL)
@@ -1791,7 +1792,17 @@ static int isp_register_entities(struct isp_device
 *isp) goto done;
 		}
 
Quoted 7 lines

drivers/media/video/omap3isp/isp.c static int isp_register_entities(struct isp_device *isp) · line 1797

Quoted 4 lines
drivers/media/video/omap3isp/isp.c +3 -1
-		ret = media_entity_create_link(&sensor->entity, 0, input, pad,
+		for (i = 0; i < sensor->entity.num_pads; i++)
+			if (sensor->entity.pads[i].flags & MEDIA_PAD_FL_SOURCE)
+				break;

While not strictly needed, I find the code easier to read with brackets for the for statement. It's up to you though.

Brackets added.

Signature · 2 lines
Sakari Ailus
e-mail: [email protected]	jabber/XMPP/Gmail: [email protected]
#74 lore raw

PATCH v5 34/35 smiapp: Generic SMIA++/SMIA PLL calculator

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

Calculate PLL configuration based on input data: sensor configuration, board properties and sensor-specific limits.

---
 drivers/media/video/Kconfig                  |    5 +
 drivers/media/video/Makefile                 |    3 +
 drivers/media/video/smiapp-pll.c             |  421 ++++
 drivers/media/video/smiapp-pll.h             |  103 +
 drivers/media/video/smiapp/Kconfig           |   13 +
 drivers/media/video/smiapp/Makefile          |    3 +
 drivers/media/video/smiapp/smiapp-core.c     | 2830 ++++++++++++++++++++++++++
 drivers/media/video/smiapp/smiapp-debug.h    |   32 +
 drivers/media/video/smiapp/smiapp-limits.c   |  132 ++
 drivers/media/video/smiapp/smiapp-limits.h   |  128 ++
 drivers/media/video/smiapp/smiapp-quirk.c    |  264 +++
 drivers/media/video/smiapp/smiapp-quirk.h    |   72 +
 drivers/media/video/smiapp/smiapp-reg-defs.h |  503 +++++
 drivers/media/video/smiapp/smiapp-reg.h      |  122 ++
 drivers/media/video/smiapp/smiapp-regs.c     |  213 ++
 drivers/media/video/smiapp/smiapp-regs.h     |   46 +
 drivers/media/video/smiapp/smiapp.h          |  251 +++
 include/media/smiapp.h                       |   83 +
 18 files changed, 5224 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/smiapp-pll.c
 create mode 100644 drivers/media/video/smiapp-pll.h
 create mode 100644 drivers/media/video/smiapp/Kconfig
 create mode 100644 drivers/media/video/smiapp/Makefile
 create mode 100644 drivers/media/video/smiapp/smiapp-core.c
 create mode 100644 drivers/media/video/smiapp/smiapp-debug.h
 create mode 100644 drivers/media/video/smiapp/smiapp-limits.c
 create mode 100644 drivers/media/video/smiapp/smiapp-limits.h
 create mode 100644 drivers/media/video/smiapp/smiapp-quirk.c
 create mode 100644 drivers/media/video/smiapp/smiapp-quirk.h
 create mode 100644 drivers/media/video/smiapp/smiapp-reg-defs.h
 create mode 100644 drivers/media/video/smiapp/smiapp-reg.h
 create mode 100644 drivers/media/video/smiapp/smiapp-regs.c
 create mode 100644 drivers/media/video/smiapp/smiapp-regs.h
 create mode 100644 drivers/media/video/smiapp/smiapp.h
 create mode 100644 include/media/smiapp.h
drivers/media/video/Kconfig +5 -0
index 9495b6a..1aaeb04 100644
@@ -459,6 +459,9 @@ config VIDEO_AK881X
 
 comment "Camera sensor devices"
 
+config VIDEO_SMIAPP_PLL
+	tristate
+
 config VIDEO_OV7670
 	tristate "OmniVision OV7670 sensor support"
 	depends on I2C && VIDEO_V4L2
@@ -524,6 +527,8 @@ 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.
 
+source "drivers/media/video/smiapp/Kconfig"
+
 comment "Flash devices"
 
 config VIDEO_ADP1653
drivers/media/video/Makefile +3 -0
index 563443c..b74f15f 100644
@@ -73,9 +73,12 @@ obj-$(CONFIG_VIDEO_SR030PC30)	+= sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)	+= noon010pc30.o
 obj-$(CONFIG_VIDEO_M5MOLS)	+= m5mols/
 obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
+obj-$(CONFIG_VIDEO_SMIAPP)	+= smiapp/
 obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
 obj-$(CONFIG_VIDEO_AS3645A)	+= as3645a.o
 
+obj-$(CONFIG_VIDEO_SMIAPP_PLL)	+= smiapp-pll.o
+
 obj-$(CONFIG_SOC_CAMERA_IMX074)		+= imx074.o
 obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
 obj-$(CONFIG_SOC_CAMERA_MT9M111)	+= mt9m111.o
drivers/media/video/smiapp-pll.c new file +421 -0

421 lines not on this page · raw message

drivers/media/video/smiapp-pll.h new file +103 -0

103 lines not on this page · raw message

drivers/media/video/smiapp/Kconfig new file +13 -0
new file mode 100644
index 0000000..9504c43
@@ -0,0 +1,13 @@
+config VIDEO_SMIAPP
+	tristate "SMIA++/SMIA sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	select VIDEO_SMIAPP_PLL
+	---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.
drivers/media/video/smiapp/Makefile new file +3 -0
new file mode 100644
index 0000000..5a207ee
@@ -0,0 +1,3 @@
+smiapp-objs			+= smiapp-core.o smiapp-regs.o \
+				   smiapp-quirk.o smiapp-limits.o
+obj-$(CONFIG_VIDEO_SMIAPP)	+= smiapp.o
drivers/media/video/smiapp/smiapp-core.c new file +2830 -0

2,431 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-debug.h new file +32 -0
new file mode 100644
index 0000000..627809e

Lines of this file are not shown. View the raw message.

drivers/media/video/smiapp/smiapp-limits.c new file +132 -0

132 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-limits.h new file +128 -0

128 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-quirk.c new file +264 -0

264 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-quirk.h new file +72 -0

72 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-reg-defs.h new file +503 -0

503 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-reg.h new file +122 -0

122 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-regs.c new file +213 -0

213 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-regs.h new file +46 -0

46 lines not on this page · raw message

drivers/media/video/smiapp/smiapp.h new file +251 -0

251 lines not on this page · raw message

include/media/smiapp.h new file +83 -0

83 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.

maintainer
#75 lore raw

Re: [PATCH v5 34/35] smiapp: Generic SMIA++/SMIA PLL calculator

Hi Sakari,

Thanks for the patch.

Quoted 6 lines · On Tuesday 06 March 2012 18:33:15 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Calculate PLL configuration based on input data: sensor configuration, board properties and sensor-specific limits.

[snip]

Quoted 5 lines
(quoted diff) +0 -0

b/drivers/media/video/smiapp-pll.c new file mode 100644 index 0000000..3a999c0

drivers/media/video/smiapp-pll.c new file +0 -0

[snip]

Quoted 4 lines

+int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,

drivers/media/video/smiapp-pll.c new file +2 -0
+			 struct smiapp_pll *pll)
+{

[snip]

Quoted 18 lines
drivers/media/video/smiapp-pll.c new file +18 -0
+	/*
+	 * Some sensors perform analogue binning and some do this
+	 * digitally. The ones doing this digitally can be roughly be
+	 * found out using this formula. The ones doing this digitally
+	 * should run at higher clock rate, so smaller divisor is used
+	 * on video timing side.
+	 */
+	if (limits->min_line_length_pck_bin > limits->min_line_length_pck
+	    / pll->binning_horizontal)
+		vt_op_binning_div = pll->binning_horizontal;
+	else
+		vt_op_binning_div = 1;
+	dev_dbg(dev, "vt_op_binning_div: %d\n", vt_op_binning_div);
+
+	/*
+	 * Profile 2 supports vt_pix_clk_div E [4, 10]
+	 *
+	 * Horizontal binning can be used as a base for difference in

drivers/media/video/smiapp-pll.c line 264

Quoted 10 lines
drivers/media/video/smiapp-pll.c new file +10 -0
+	 * divisors. One must make sure that horizontal blanking is
+	 * enough to accommodate the CSI-2 sync codes.
+	 *
+	 * Take scaling factor into account as well.
+	 *
+	 * Find absolute limits for the factor of vt divider.
+	 */
+	dev_dbg(dev, "scale_m: %d\n", pll->scale_m);
+	min_vt_div = DIV_ROUND_UP(pll->op_pix_clk_div * pll->op_sys_clk_div
+				  * pll->scale_n,

I still need

        if (pll->flags & SMIAPP_PLL_FLAG_DUAL_READOUT)
               num_readout_paths = 2;
        else
               num_readout_paths = 1;
        min_vt_div = DIV_ROUND_UP(pll->op_pix_clk_div * pll->op_sys_clk_div
                                 * pll->scale_n * num_readout_paths,

for the AR0330 driver, but I can add that later.

Quoted 2 lines
drivers/media/video/smiapp-pll.c new file +2 -0
+				  lane_op_clock_ratio * vt_op_binning_div
+				  * pll->scale_m);

[snip]

Quoted 6 lines
drivers/media/video/smiapp-pll.c new file +6 -0
+	/*
+	 * Find pix_div such that a legal pix_div * sys_div results
+	 * into a value which is not smaller than div, the desired
+	 * divisor.
+	 */
+	for (vt_div = min_vt_div; vt_div <= max_vt_div;

drivers/media/video/smiapp-pll.c line 331

Quoted 10 lines
drivers/media/video/smiapp-pll.c new file +10 -0
+	     vt_div += 2 - (vt_div & 1)) {
+		for (sys_div = min_sys_div;
+		     sys_div <= max_sys_div;
+		     sys_div += 2 - (sys_div & 1)) {
+			int pix_div = DIV_ROUND_UP(vt_div, sys_div);
+
+			if (pix_div <
+			    limits->min_vt_pix_clk_div
+			    || pix_div
+			    > limits->max_vt_pix_clk_div) {
			if (pix_div < limits->min_vt_pix_clk_div ||
			    pix_div > limits->max_vt_pix_clk_div) {
Quoted 16 lines
drivers/media/video/smiapp-pll.c new file +16 -0
+				dev_dbg(dev,
+					"pix_div %d too small or too big (%d--%d)\n",
+					pix_div,
+					limits->min_vt_pix_clk_div,
+					limits->max_vt_pix_clk_div);
+				continue;
+			}
+
+			/* Check if this one is better. */
+			if (pix_div * sys_div
+			    <= ALIGN(min_vt_div, best_pix_div))
+				best_pix_div = pix_div;
+		}
+		if (best_pix_div < INT_MAX >> 1)
+			break;
+	}

[snip]

Quoted 5 lines
(quoted diff) +0 -0

b/drivers/media/video/smiapp/smiapp-core.c new file mode 100644 index 0000000..879fb1e

drivers/media/video/smiapp/smiapp-core.c new file +0 -0

[snip]

drivers/media/video/smiapp/smiapp-core.c line 1564

Quoted 7 lines
drivers/media/video/smiapp/smiapp-core.c new file +7 -0
+static void smiapp_get_crop_compose(struct v4l2_subdev *subdev,
+				    struct v4l2_subdev_fh *fh,
+				    struct v4l2_rect **crops,
+				    struct v4l2_rect **comps, int which)
+{
+	struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
+	int i;

Can you guess ? :-)

Quoted 21 lines
drivers/media/video/smiapp/smiapp-core.c new file +21 -0
+
+	if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		if (crops)
+			for (i = 0; i < subdev->entity.num_pads; i++)
+				crops[i] = &ssd->crop[i];
+		if (comps)
+			*comps = &ssd->compose;
+	} else {
+		if (crops) {
+			for (i = 0; i < subdev->entity.num_pads; i++) {
+				crops[i] = v4l2_subdev_get_try_crop(fh, i);
+				BUG_ON(!crops[i]);
+			}
+		}
+		if (comps) {
+			*comps = v4l2_subdev_get_try_compose(fh,
+							     SMIAPP_PAD_SINK);
+			BUG_ON(!*comps);
+		}
+	}
+}

[snip]

drivers/media/video/smiapp/smiapp-core.c line 1631

Quoted 9 lines
drivers/media/video/smiapp/smiapp-core.c new file +9 -0
+static int smiapp_set_format(struct v4l2_subdev *subdev,
+			     struct v4l2_subdev_fh *fh,
+			     struct v4l2_subdev_format *fmt)
+{
+	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+	struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
+	struct v4l2_rect *crops[SMIAPP_PADS];
+	const struct smiapp_csi_data_format *csi_format = sensor->csi_format;
+	int i;

:-D

Quoted 19 lines
drivers/media/video/smiapp/smiapp-core.c new file +19 -0
+
+	mutex_lock(&sensor->mutex);
+
+	smiapp_get_crop_compose(subdev, fh, crops, NULL, fmt->which);
+
+	if (subdev == &sensor->src->sd && fmt->pad == SMIAPP_PAD_SRC) {
+		for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) {
+			if (sensor->mbus_frame_fmts & (1 << i) &&
+			    smiapp_csi_data_formats[i].code
+			    == fmt->format.code) {
+				csi_format = &smiapp_csi_data_formats[i];
+				if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+					sensor->csi_format = csi_format;
+				break;
+			}
+		}
+	}
+
+	if (fmt->pad == ssd->source_pad) {

drivers/media/video/smiapp/smiapp-core.c line 1660

Quoted 10 lines
drivers/media/video/smiapp/smiapp-core.c new file +10 -0
+		int rval;
+
+		rval = __smiapp_get_format(subdev, fh, fmt);
+		fmt->format.code = csi_format->code;
+
+		mutex_unlock(&sensor->mutex);
+		return rval;
+	}
+
+	fmt->format.code = csi_format->code;

This will result in the format code at the output of the pixel array being equal to the format code at the output of the binner/scaler. I don't think you want that.

You probably need to take a small step back and rethink the code flow in this function a bit. I'm pretty sure you can keep it simple.

Quoted 25 lines
drivers/media/video/smiapp/smiapp-core.c new file +25 -0
+	fmt->format.width &= ~1;
+	fmt->format.height &= ~1;
+
+	fmt->format.width =
+		clamp(fmt->format.width,
+		      sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
+		      sensor->limits[SMIAPP_LIMIT_MAX_X_OUTPUT_SIZE]);
+	fmt->format.height =
+		clamp(fmt->format.height,
+		      sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],
+		      sensor->limits[SMIAPP_LIMIT_MAX_Y_OUTPUT_SIZE]);
+
+	crops[ssd->sink_pad]->left = 0;
+	crops[ssd->sink_pad]->top = 0;
+	crops[ssd->sink_pad]->width = fmt->format.width;
+	crops[ssd->sink_pad]->height = fmt->format.height;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+		ssd->sink_fmt = *crops[ssd->sink_pad];
+	smiapp_propagate(subdev, fh, fmt->which,
+			 V4L2_SUBDEV_SEL_TGT_CROP_ACTIVE);
+
+	mutex_unlock(&sensor->mutex);
+
+	return 0;
+}

[snip]

Signature · 3 lines
Regards,

Laurent Pinchart
#76 lore raw

Re: [PATCH v5 34/35] smiapp: Generic SMIA++/SMIA PLL calculator

Hi Laurent,

Quoted 1 line · Laurent Pinchart

Thanks for the patch.

Thanks for the comments!

Quoted 56 lines · On Tuesday 06 March 2012 18:33:15 Sakari Ailus wrote:
Quoted 6 lines

From: Sakari Ailus <[email protected]>

Calculate PLL configuration based on input data: sensor configuration, board properties and sensor-specific limits.

[snip]

Quoted 5 lines
(quoted diff) +0 -0

b/drivers/media/video/smiapp-pll.c new file mode 100644 index 0000000..3a999c0

drivers/media/video/smiapp-pll.c new file +0 -0

[snip]

Quoted 4 lines

+int smiapp_pll_calculate(struct device *dev, struct smiapp_pll_limits *limits,

drivers/media/video/smiapp-pll.c new file +2 -0
+			 struct smiapp_pll *pll)
+{

[snip]

Quoted 18 lines
drivers/media/video/smiapp-pll.c new file +18 -0
+	/*
+	 * Some sensors perform analogue binning and some do this
+	 * digitally. The ones doing this digitally can be roughly be
+	 * found out using this formula. The ones doing this digitally
+	 * should run at higher clock rate, so smaller divisor is used
+	 * on video timing side.
+	 */
+	if (limits->min_line_length_pck_bin > limits->min_line_length_pck
+	    / pll->binning_horizontal)
+		vt_op_binning_div = pll->binning_horizontal;
+	else
+		vt_op_binning_div = 1;
+	dev_dbg(dev, "vt_op_binning_div: %d\n", vt_op_binning_div);
+
+	/*
+	 * Profile 2 supports vt_pix_clk_div E [4, 10]
+	 *
+	 * Horizontal binning can be used as a base for difference in

drivers/media/video/smiapp-pll.c line 264

Quoted 10 lines
drivers/media/video/smiapp-pll.c new file +10 -0
+	 * divisors. One must make sure that horizontal blanking is
+	 * enough to accommodate the CSI-2 sync codes.
+	 *
+	 * Take scaling factor into account as well.
+	 *
+	 * Find absolute limits for the factor of vt divider.
+	 */
+	dev_dbg(dev, "scale_m: %d\n", pll->scale_m);
+	min_vt_div = DIV_ROUND_UP(pll->op_pix_clk_div * pll->op_sys_clk_div
+				  * pll->scale_n,

I still need

Quoted 8 lines
        if (pll->flags & SMIAPP_PLL_FLAG_DUAL_READOUT)
               num_readout_paths = 2;
        else
               num_readout_paths = 1;
        min_vt_div = DIV_ROUND_UP(pll->op_pix_clk_div * pll->op_sys_clk_div
                                 * pll->scale_n * num_readout_paths,

for the AR0330 driver, but I can add that later.

Here?

That should come from lane_op_clock_ratio if your sensor needs that.

Quoted 16 lines
Quoted 2 lines
drivers/media/video/smiapp-pll.c new file +2 -0
+				  lane_op_clock_ratio * vt_op_binning_div
+				  * pll->scale_m);

[snip]

Quoted 11 lines
drivers/media/video/smiapp-pll.c new file +11 -0
+	/*
+	 * Find pix_div such that a legal pix_div * sys_div results
+	 * into a value which is not smaller than div, the desired
+	 * divisor.
+	 */
+	for (vt_div = min_vt_div; vt_div <= max_vt_div;
+	     vt_div += 2 - (vt_div & 1)) {
+		for (sys_div = min_sys_div;
+		     sys_div <= max_sys_div;
+		     sys_div += 2 - (sys_div & 1)) {
+			int pix_div = DIV_ROUND_UP(vt_div, sys_div);
Quoted 8 lines

drivers/media/video/smiapp-pll.c line 331

Quoted 5 lines
drivers/media/video/smiapp-pll.c new file +5 -0
+
+			if (pix_div <
+			    limits->min_vt_pix_clk_div
+			    || pix_div
+			    > limits->max_vt_pix_clk_div) {
			if (pix_div < limits->min_vt_pix_clk_div ||
			    pix_div > limits->max_vt_pix_clk_div) {

Will fix.

Quoted 19 lines
Quoted 16 lines
drivers/media/video/smiapp-pll.c new file +16 -0
+				dev_dbg(dev,
+					"pix_div %d too small or too big (%d--%d)\n",
+					pix_div,
+					limits->min_vt_pix_clk_div,
+					limits->max_vt_pix_clk_div);
+				continue;
+			}
+
+			/* Check if this one is better. */
+			if (pix_div * sys_div
+			    <= ALIGN(min_vt_div, best_pix_div))
+				best_pix_div = pix_div;
+		}
+		if (best_pix_div < INT_MAX >> 1)
+			break;
+	}

[snip]

Quoted 5 lines

drivers/media/video/smiapp/smiapp-core.c

Quoted 5 lines
(quoted diff) +0 -0

b/drivers/media/video/smiapp/smiapp-core.c new file mode 100644 index 0000000..879fb1e

drivers/media/video/smiapp/smiapp-core.c new file +0 -0

I think I accidentally combined the two patches. I'll separate them again.

Quoted 12 lines

[snip]

drivers/media/video/smiapp/smiapp-core.c line 1564

Quoted 7 lines
drivers/media/video/smiapp/smiapp-core.c new file +7 -0
+static void smiapp_get_crop_compose(struct v4l2_subdev *subdev,
+				    struct v4l2_subdev_fh *fh,
+				    struct v4l2_rect **crops,
+				    struct v4l2_rect **comps, int which)
+{
+	struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
+	int i;

Can you guess ? :-)

Hmm. signed? unsigned? int8_t? bool? :-D

Quoted 24 lines
Quoted 21 lines
drivers/media/video/smiapp/smiapp-core.c new file +21 -0
+
+	if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		if (crops)
+			for (i = 0; i < subdev->entity.num_pads; i++)
+				crops[i] = &ssd->crop[i];
+		if (comps)
+			*comps = &ssd->compose;
+	} else {
+		if (crops) {
+			for (i = 0; i < subdev->entity.num_pads; i++) {
+				crops[i] = v4l2_subdev_get_try_crop(fh, i);
+				BUG_ON(!crops[i]);
+			}
+		}
+		if (comps) {
+			*comps = v4l2_subdev_get_try_compose(fh,
+							     SMIAPP_PAD_SINK);
+			BUG_ON(!*comps);
+		}
+	}
+}

[snip]

Quoted 11 lines

drivers/media/video/smiapp/smiapp-core.c line 1631

Quoted 9 lines
drivers/media/video/smiapp/smiapp-core.c new file +9 -0
+static int smiapp_set_format(struct v4l2_subdev *subdev,
+			     struct v4l2_subdev_fh *fh,
+			     struct v4l2_subdev_format *fmt)
+{
+	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+	struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
+	struct v4l2_rect *crops[SMIAPP_PADS];
+	const struct smiapp_csi_data_format *csi_format = sensor->csi_format;
+	int i;

:-D

I will replace "int" with "unsigned". :-D

Quoted 25 lines
Quoted 25 lines
drivers/media/video/smiapp/smiapp-core.c new file +25 -0
+
+	mutex_lock(&sensor->mutex);
+
+	smiapp_get_crop_compose(subdev, fh, crops, NULL, fmt->which);
+
+	if (subdev == &sensor->src->sd && fmt->pad == SMIAPP_PAD_SRC) {
+		for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) {
+			if (sensor->mbus_frame_fmts & (1 << i) &&
+			    smiapp_csi_data_formats[i].code
+			    == fmt->format.code) {
+				csi_format = &smiapp_csi_data_formats[i];
+				if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+					sensor->csi_format = csi_format;
+				break;
+			}
+		}
+	}
+
+	if (fmt->pad == ssd->source_pad) {
+		int rval;
+
+		rval = __smiapp_get_format(subdev, fh, fmt);
+		fmt->format.code = csi_format->code;
+
+		mutex_unlock(&sensor->mutex);
Quoted 8 lines

drivers/media/video/smiapp/smiapp-core.c line 1660

Quoted 4 lines
drivers/media/video/smiapp/smiapp-core.c new file +4 -0
+		return rval;
+	}
+
+	fmt->format.code = csi_format->code;

This will result in the format code at the output of the pixel array being equal to the format code at the output of the binner/scaler. I don't think you want that.

Good point. I created another function to get that information that also __smiapp_get_format() uses.

Kind regards,

Signature · 2 lines
Sakari Ailus
e-mail: [email protected]	jabber/XMPP/Gmail: [email protected]
#77 lore raw

PATCH v5 34/35 smiapp: Generic SMIA++/SMIA PLL calculator

In reply to Laurent Pinchart

From: Sakari Ailus <[email protected]>

Calculate PLL configuration based on input data: sensor configuration, board properties and sensor-specific limits.

---
 drivers/media/video/Kconfig      |    3 +
 drivers/media/video/Makefile     |    2 +
 drivers/media/video/smiapp-pll.c |  419 ++++++++++++++++++++++++++++++++++++++
 drivers/media/video/smiapp-pll.h |  103 ++++++++++
 4 files changed, 527 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/smiapp-pll.c
 create mode 100644 drivers/media/video/smiapp-pll.h
drivers/media/video/Kconfig +3 -0
index 9495b6a..7eac873 100644
@@ -459,6 +459,9 @@ config VIDEO_AK881X
 
 comment "Camera sensor devices"
 
+config VIDEO_SMIAPP_PLL
+	tristate
+
 config VIDEO_OV7670
 	tristate "OmniVision OV7670 sensor support"
 	depends on I2C && VIDEO_V4L2
drivers/media/video/Makefile +2 -0
index 563443c..2fed63d 100644
@@ -76,6 +76,8 @@ obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
 obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
 obj-$(CONFIG_VIDEO_AS3645A)	+= as3645a.o
 
+obj-$(CONFIG_VIDEO_SMIAPP_PLL)	+= smiapp-pll.o
+
 obj-$(CONFIG_SOC_CAMERA_IMX074)		+= imx074.o
 obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
 obj-$(CONFIG_SOC_CAMERA_MT9M111)	+= mt9m111.o
drivers/media/video/smiapp-pll.c new file +419 -0

419 lines not on this page · raw message

drivers/media/video/smiapp-pll.h new file +103 -0

103 lines not on this page · raw message

Signature · 1 line
1.7.2.5
maintainer
#78 lore raw

Re: [PATCH v5.1 34/35] smiapp: Generic SMIA++/SMIA PLL calculator

Hi Sakari,

Thanks for the patch.

Quoted 6 lines · On Thursday 08 March 2012 15:57:29 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Calculate PLL configuration based on input data: sensor configuration, board properties and sensor-specific limits.

[snip]

Quoted 5 lines
(quoted diff) +0 -0

b/drivers/media/video/smiapp-pll.c new file mode 100644 index 0000000..c8ffdc9

drivers/media/video/smiapp-pll.c new file +0 -0

[snip]

Quoted 6 lines
drivers/media/video/smiapp-pll.c new file +6 -0
+	/*
+	 * Find pix_div such that a legal pix_div * sys_div results
+	 * into a value which is not smaller than div, the desired
+	 * divisor.
+	 */
+	for (vt_div = min_vt_div; vt_div <= max_vt_div;

drivers/media/video/smiapp-pll.c line 329

Quoted 10 lines
drivers/media/video/smiapp-pll.c new file +10 -0
+	     vt_div += 2 - (vt_div & 1)) {
+		for (sys_div = min_sys_div;
+		     sys_div <= max_sys_div;
+		     sys_div += 2 - (sys_div & 1)) {
+			int pix_div = DIV_ROUND_UP(vt_div, sys_div);
+
+			if (pix_div <
+			    limits->min_vt_pix_clk_div
+			    || pix_div
+			    > limits->max_vt_pix_clk_div) {

Maybe you should get some sleep, I've heard it helps memory ;-)

Quoted 16 lines
drivers/media/video/smiapp-pll.c new file +16 -0
+				dev_dbg(dev,
+					"pix_div %d too small or too big (%d--%d)\n",
+					pix_div,
+					limits->min_vt_pix_clk_div,
+					limits->max_vt_pix_clk_div);
+				continue;
+			}
+
+			/* Check if this one is better. */
+			if (pix_div * sys_div
+			    <= ALIGN(min_vt_div, best_pix_div))
+				best_pix_div = pix_div;
+		}
+		if (best_pix_div < INT_MAX >> 1)
+			break;
+	}
Signature · 3 lines
Regards,

Laurent Pinchart
#79 lore raw

Re: [PATCH v5.1 34/35] smiapp: Generic SMIA++/SMIA PLL calculator

Hi Laurent,

Quoted 32 lines · Laurent Pinchart

Hi Sakari,

Thanks for the patch.

Quoted 6 lines · On Thursday 08 March 2012 15:57:29 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Calculate PLL configuration based on input data: sensor configuration, board properties and sensor-specific limits.

[snip]

Quoted 5 lines
(quoted diff) +0 -0

b/drivers/media/video/smiapp-pll.c new file mode 100644 index 0000000..c8ffdc9

drivers/media/video/smiapp-pll.c new file +0 -0

[snip]

Quoted 10 lines
drivers/media/video/smiapp-pll.c new file +10 -0
+	/*
+	 * Find pix_div such that a legal pix_div * sys_div results
+	 * into a value which is not smaller than div, the desired
+	 * divisor.
+	 */
+	for (vt_div = min_vt_div; vt_div <= max_vt_div;
+	     vt_div += 2 - (vt_div & 1)) {
+		for (sys_div = min_sys_div;
+		     sys_div <= max_sys_div;
+		     sys_div += 2 - (sys_div & 1)) {
Quoted 8 lines

drivers/media/video/smiapp-pll.c line 329

Quoted 6 lines
drivers/media/video/smiapp-pll.c new file +6 -0
+			int pix_div = DIV_ROUND_UP(vt_div, sys_div);
+
+			if (pix_div <
+			    limits->min_vt_pix_clk_div
+			    || pix_div
+			    > limits->max_vt_pix_clk_div) {

Maybe you should get some sleep, I've heard it helps memory ;-)

Oh. That's what it was. I didn't find it the first time. Sorry about that.

I'll send a new version where that has been fixed.

Signature · 2 lines
Sakari Ailus
e-mail: [email protected]	jabber/XMPP/Gmail: [email protected]
#80 lore raw

PATCH v5 34/35 smiapp: Generic SMIA++/SMIA PLL calculator

In reply to Laurent Pinchart

From: Sakari Ailus <[email protected]>

Calculate PLL configuration based on input data: sensor configuration, board properties and sensor-specific limits.

---
 drivers/media/video/Kconfig      |    3 +
 drivers/media/video/Makefile     |    2 +
 drivers/media/video/smiapp-pll.c |  417 ++++++++++++++++++++++++++++++++++++++
 drivers/media/video/smiapp-pll.h |  103 ++++++++++
 4 files changed, 525 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/smiapp-pll.c
 create mode 100644 drivers/media/video/smiapp-pll.h
drivers/media/video/Kconfig +3 -0
index 9495b6a..7eac873 100644
@@ -459,6 +459,9 @@ config VIDEO_AK881X
 
 comment "Camera sensor devices"
 
+config VIDEO_SMIAPP_PLL
+	tristate
+
 config VIDEO_OV7670
 	tristate "OmniVision OV7670 sensor support"
 	depends on I2C && VIDEO_V4L2
drivers/media/video/Makefile +2 -0
index 563443c..2fed63d 100644
@@ -76,6 +76,8 @@ obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
 obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
 obj-$(CONFIG_VIDEO_AS3645A)	+= as3645a.o
 
+obj-$(CONFIG_VIDEO_SMIAPP_PLL)	+= smiapp-pll.o
+
 obj-$(CONFIG_SOC_CAMERA_IMX074)		+= imx074.o
 obj-$(CONFIG_SOC_CAMERA_MT9M001)	+= mt9m001.o
 obj-$(CONFIG_SOC_CAMERA_MT9M111)	+= mt9m111.o
drivers/media/video/smiapp-pll.c new file +417 -0

417 lines not on this page · raw message

drivers/media/video/smiapp-pll.h new file +103 -0

103 lines not on this page · raw message

Signature · 1 line
1.7.2.5
maintainer Acked-by on v5 34/35
#81 lore raw

Re: [PATCH v5.2 34/35] smiapp: Generic SMIA++/SMIA PLL calculator

Quoted 6 lines · On Thursday 08 March 2012 16:49:14 Sakari Ailus wrote:

From: Sakari Ailus <[email protected]>

Calculate PLL configuration based on input data: sensor configuration, board properties and sensor-specific limits.

Signature · 3 lines
Regards,

Laurent Pinchart
#82 lore raw

PATCH v5 35/35 smiapp: Add driver

In reply to Laurent Pinchart

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                  |    2 +
 drivers/media/video/Makefile                 |    1 +
 drivers/media/video/smiapp-pll.c             |    2 +
 drivers/media/video/smiapp/Kconfig           |   13 +
 drivers/media/video/smiapp/Makefile          |    3 +
 drivers/media/video/smiapp/smiapp-core.c     | 2826 ++++++++++++++++++++++++++
 drivers/media/video/smiapp/smiapp-debug.h    |   32 +
 drivers/media/video/smiapp/smiapp-limits.c   |  132 ++
 drivers/media/video/smiapp/smiapp-limits.h   |  128 ++
 drivers/media/video/smiapp/smiapp-quirk.c    |  264 +++
 drivers/media/video/smiapp/smiapp-quirk.h    |   72 +
 drivers/media/video/smiapp/smiapp-reg-defs.h |  503 +++++
 drivers/media/video/smiapp/smiapp-reg.h      |  122 ++
 drivers/media/video/smiapp/smiapp-regs.c     |  213 ++
 drivers/media/video/smiapp/smiapp-regs.h     |   46 +
 drivers/media/video/smiapp/smiapp.h          |  251 +++
 include/media/smiapp.h                       |   83 +
 17 files changed, 4693 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/smiapp/Kconfig
 create mode 100644 drivers/media/video/smiapp/Makefile
 create mode 100644 drivers/media/video/smiapp/smiapp-core.c
 create mode 100644 drivers/media/video/smiapp/smiapp-debug.h
 create mode 100644 drivers/media/video/smiapp/smiapp-limits.c
 create mode 100644 drivers/media/video/smiapp/smiapp-limits.h
 create mode 100644 drivers/media/video/smiapp/smiapp-quirk.c
 create mode 100644 drivers/media/video/smiapp/smiapp-quirk.h
 create mode 100644 drivers/media/video/smiapp/smiapp-reg-defs.h
 create mode 100644 drivers/media/video/smiapp/smiapp-reg.h
 create mode 100644 drivers/media/video/smiapp/smiapp-regs.c
 create mode 100644 drivers/media/video/smiapp/smiapp-regs.h
 create mode 100644 drivers/media/video/smiapp/smiapp.h
 create mode 100644 include/media/smiapp.h
drivers/media/video/Kconfig +2 -0
index 7eac873..1aaeb04 100644
@@ -527,6 +527,8 @@ 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.
 
+source "drivers/media/video/smiapp/Kconfig"
+
 comment "Flash devices"
 
 config VIDEO_ADP1653
drivers/media/video/Makefile +1 -0
index 2fed63d..b74f15f 100644
@@ -73,6 +73,7 @@ obj-$(CONFIG_VIDEO_SR030PC30)	+= sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)	+= noon010pc30.o
 obj-$(CONFIG_VIDEO_M5MOLS)	+= m5mols/
 obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
+obj-$(CONFIG_VIDEO_SMIAPP)	+= smiapp/
 obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
 obj-$(CONFIG_VIDEO_AS3645A)	+= as3645a.o
 
drivers/media/video/smiapp-pll.c +2 -0
index c8ffdc9..be7a543 100644
@@ -22,6 +22,8 @@
  *
  */
 
+#include "smiapp/smiapp-debug.h"
+
 #include <linux/gcd.h>
 #include <linux/lcm.h>
 #include <linux/module.h>
drivers/media/video/smiapp/Kconfig new file +13 -0
new file mode 100644
index 0000000..9504c43
@@ -0,0 +1,13 @@
+config VIDEO_SMIAPP
+	tristate "SMIA++/SMIA sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	select VIDEO_SMIAPP_PLL
+	---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.
drivers/media/video/smiapp/Makefile new file +3 -0
new file mode 100644
index 0000000..5a207ee
@@ -0,0 +1,3 @@
+smiapp-objs			+= smiapp-core.o smiapp-regs.o \
+				   smiapp-quirk.o smiapp-limits.o
+obj-$(CONFIG_VIDEO_SMIAPP)	+= smiapp.o
drivers/media/video/smiapp/smiapp-core.c new file +2826 -0

2,826 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-debug.h new file +32 -0
new file mode 100644
index 0000000..627809e
@@ -0,0 +1,32 @@
+/*
+ * drivers/media/video/smiapp/smiapp-debug.h
+ *
+ * Generic driver for SMIA/SMIA++ compliant camera modules
+ *
+ * Copyright (C) 2011--2012 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/smiapp-limits.c new file +132 -0

103 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-limits.h new file +128 -0

128 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-quirk.c new file +264 -0

264 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-quirk.h new file +72 -0

72 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-reg-defs.h new file +503 -0

503 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-reg.h new file +122 -0

122 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-regs.c new file +213 -0

213 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-regs.h new file +46 -0

46 lines not on this page · raw message

drivers/media/video/smiapp/smiapp.h new file +251 -0

251 lines not on this page · raw message

include/media/smiapp.h new file +83 -0

83 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.

maintainer
#83 lore raw

Re: [PATCH v5.1 35/35] smiapp: Add driver

Hi Sakari,

Thanks for the patch.

Quoted 8 lines · On Thursday 08 March 2012 15:57:30 Sakari Ailus wrote:

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.

[snip]

Quoted 27 lines
drivers/media/video/smiapp/smiapp-core.c new file +8 -0
+static int smiapp_set_format(struct v4l2_subdev *subdev,
+                            struct v4l2_subdev_fh *fh,
+                            struct v4l2_subdev_format *fmt)
+{
+       struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+       struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
+       struct v4l2_rect *crops[SMIAPP_PADS];
+       const struct smiapp_csi_data_format *csi_format = sensor-
Quoted 1 line

csi_format;

drivers/media/video/smiapp/smiapp-core.c new file +18 -0
+       unsigned i;
+
+       mutex_lock(&sensor->mutex);
+
+       smiapp_get_crop_compose(subdev, fh, crops, NULL, fmt->which);
+
+       if (subdev == &sensor->src->sd && fmt->pad == SMIAPP_PAD_SRC) {
+               for (i = 0; i < ARRAY_SIZE(smiapp_csi_data_formats); i++) {
+                       if (sensor->mbus_frame_fmts & (1 << i) &&
+                           smiapp_csi_data_formats[i].code
+                           == fmt->format.code) {
+                               csi_format = &smiapp_csi_data_formats[i];
+                               if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+                                       sensor->csi_format = csi_format;
+                               break;
+                       }
+               }
+       }

drivers/media/video/smiapp/smiapp-core.c line 1670

Quoted 10 lines
drivers/media/video/smiapp/smiapp-core.c new file +10 -0
+
+       if (fmt->pad == ssd->source_pad) {
+               int rval;
+
+               rval = __smiapp_get_format(subdev, fh, fmt);
+               fmt->format.code = csi_format->code;
+
+               mutex_unlock(&sensor->mutex);
+               return rval;
+       }

That's still not good I'm afraid. The pixel array source format code will be set to the sensor source format code, which isn't right.

Quoted 27 lines
drivers/media/video/smiapp/smiapp-core.c new file +27 -0
+
+       fmt->format.code = __smiapp_get_mbus_code(subdev, fmt->pad);
+       fmt->format.width &= ~1;
+       fmt->format.height &= ~1;
+
+       fmt->format.width =
+               clamp(fmt->format.width,
+                     sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
+                     sensor->limits[SMIAPP_LIMIT_MAX_X_OUTPUT_SIZE]);
+       fmt->format.height =
+               clamp(fmt->format.height,
+                     sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],
+                     sensor->limits[SMIAPP_LIMIT_MAX_Y_OUTPUT_SIZE]);
+
+       crops[ssd->sink_pad]->left = 0;
+       crops[ssd->sink_pad]->top = 0;
+       crops[ssd->sink_pad]->width = fmt->format.width;
+       crops[ssd->sink_pad]->height = fmt->format.height;
+       if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+               ssd->sink_fmt = *crops[ssd->sink_pad];
+       smiapp_propagate(subdev, fh, fmt->which,
+                        V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL);
+
+       mutex_unlock(&sensor->mutex);
+
+       return 0;
+}
Signature · 3 lines
Regards,

Laurent Pinchart
#84 lore raw

PATCH v5 35/35 smiapp: Add driver

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                  |    2 +
 drivers/media/video/Makefile                 |    1 +
 drivers/media/video/smiapp-pll.c             |    2 +
 drivers/media/video/smiapp/Kconfig           |   13 +
 drivers/media/video/smiapp/Makefile          |    3 +
 drivers/media/video/smiapp/smiapp-core.c     | 2831 ++++++++++++++++++++++++++
 drivers/media/video/smiapp/smiapp-debug.h    |   32 +
 drivers/media/video/smiapp/smiapp-limits.c   |  132 ++
 drivers/media/video/smiapp/smiapp-limits.h   |  128 ++
 drivers/media/video/smiapp/smiapp-quirk.c    |  264 +++
 drivers/media/video/smiapp/smiapp-quirk.h    |   72 +
 drivers/media/video/smiapp/smiapp-reg-defs.h |  503 +++++
 drivers/media/video/smiapp/smiapp-reg.h      |  122 ++
 drivers/media/video/smiapp/smiapp-regs.c     |  213 ++
 drivers/media/video/smiapp/smiapp-regs.h     |   46 +
 drivers/media/video/smiapp/smiapp.h          |  251 +++
 include/media/smiapp.h                       |   83 +
 17 files changed, 4698 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/smiapp/Kconfig
 create mode 100644 drivers/media/video/smiapp/Makefile
 create mode 100644 drivers/media/video/smiapp/smiapp-core.c
 create mode 100644 drivers/media/video/smiapp/smiapp-debug.h
 create mode 100644 drivers/media/video/smiapp/smiapp-limits.c
 create mode 100644 drivers/media/video/smiapp/smiapp-limits.h
 create mode 100644 drivers/media/video/smiapp/smiapp-quirk.c
 create mode 100644 drivers/media/video/smiapp/smiapp-quirk.h
 create mode 100644 drivers/media/video/smiapp/smiapp-reg-defs.h
 create mode 100644 drivers/media/video/smiapp/smiapp-reg.h
 create mode 100644 drivers/media/video/smiapp/smiapp-regs.c
 create mode 100644 drivers/media/video/smiapp/smiapp-regs.h
 create mode 100644 drivers/media/video/smiapp/smiapp.h
 create mode 100644 include/media/smiapp.h
drivers/media/video/Kconfig +2 -0
index 7eac873..1aaeb04 100644
@@ -527,6 +527,8 @@ 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.
 
+source "drivers/media/video/smiapp/Kconfig"
+
 comment "Flash devices"
 
 config VIDEO_ADP1653
drivers/media/video/Makefile +1 -0
index 2fed63d..b74f15f 100644
@@ -73,6 +73,7 @@ obj-$(CONFIG_VIDEO_SR030PC30)	+= sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)	+= noon010pc30.o
 obj-$(CONFIG_VIDEO_M5MOLS)	+= m5mols/
 obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
+obj-$(CONFIG_VIDEO_SMIAPP)	+= smiapp/
 obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
 obj-$(CONFIG_VIDEO_AS3645A)	+= as3645a.o
 
drivers/media/video/smiapp-pll.c +2 -0
index be63bb4..326bd0e 100644
@@ -22,6 +22,8 @@
  *
  */
 
+#include "smiapp/smiapp-debug.h"
+
 #include <linux/gcd.h>
 #include <linux/lcm.h>
 #include <linux/module.h>
drivers/media/video/smiapp/Kconfig new file +13 -0
new file mode 100644
index 0000000..9504c43
@@ -0,0 +1,13 @@
+config VIDEO_SMIAPP
+	tristate "SMIA++/SMIA sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	select VIDEO_SMIAPP_PLL
+	---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.
drivers/media/video/smiapp/Makefile new file +3 -0
new file mode 100644
index 0000000..5a207ee
@@ -0,0 +1,3 @@
+smiapp-objs			+= smiapp-core.o smiapp-regs.o \
+				   smiapp-quirk.o smiapp-limits.o
+obj-$(CONFIG_VIDEO_SMIAPP)	+= smiapp.o
drivers/media/video/smiapp/smiapp-core.c new file +2831 -0

2,831 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-debug.h new file +32 -0
new file mode 100644
index 0000000..627809e
@@ -0,0 +1,32 @@
+/*
+ * drivers/media/video/smiapp/smiapp-debug.h
+ *
+ * Generic driver for SMIA/SMIA++ compliant camera modules
+ *
+ * Copyright (C) 2011--2012 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/smiapp-limits.c new file +132 -0

98 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-limits.h new file +128 -0

128 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-quirk.c new file +264 -0

264 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-quirk.h new file +72 -0

72 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-reg-defs.h new file +503 -0

503 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-reg.h new file +122 -0

122 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-regs.c new file +213 -0

213 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-regs.h new file +46 -0

46 lines not on this page · raw message

drivers/media/video/smiapp/smiapp.h new file +251 -0

251 lines not on this page · raw message

include/media/smiapp.h new file +83 -0

83 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.

maintainer
#85 lore raw

Re: [PATCH v5.3 35/35] smiapp: Add driver

Hi Sakari,

Thanks for the patch.

Quoted 10 lines · On Thursday 08 March 2012 18:49:43 Sakari Ailus wrote:

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.

[snip]

drivers/media/video/smiapp-pll.c line 26

Quoted 10 lines
(quoted diff) +0 -0

b/drivers/media/video/smiapp-pll.c index be63bb4..326bd0e 100644

drivers/media/video/smiapp-pll.c +2 -0
@@ -22,6 +22,8 @@
  *
  */
 
+#include "smiapp/smiapp-debug.h"
+

Is this needed ?

drivers/media/video/smiapp-pll.c line 29

Quoted 3 lines
drivers/media/video/smiapp-pll.c +0 -0
 #include <linux/gcd.h>
 #include <linux/lcm.h>
 #include <linux/module.h>

[snio]

Quoted 5 lines
(quoted diff) +0 -0

b/drivers/media/video/smiapp/smiapp-core.c new file mode 100644 index 0000000..68f4397

drivers/media/video/smiapp/smiapp-core.c new file +0 -0

[snip]

Quoted 7 lines
drivers/media/video/smiapp/smiapp-core.c new file +7 -0
+static int smiapp_set_format(struct v4l2_subdev *subdev,
+			     struct v4l2_subdev_fh *fh,
+			     struct v4l2_subdev_format *fmt)
+{
+	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+	struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
+	struct v4l2_rect *crops[SMIAPP_PADS];

drivers/media/video/smiapp/smiapp-core.c line 1661

Quoted 10 lines
drivers/media/video/smiapp/smiapp-core.c new file +10 -0
+	const struct smiapp_csi_data_format *csi_format;
+
+	mutex_lock(&sensor->mutex);
+
+	/*
+	 * Media bus code is changeable on src subdev's source pad. On
+	 * other source pads we just get format here.
+	 */
+	if (fmt->pad == ssd->source_pad) {
+		int rval = __smiapp_get_format(subdev, fh, fmt);

This overwrites fmt completely, you won't be able to change it at all.

Quoted 41 lines
drivers/media/video/smiapp/smiapp-core.c new file +41 -0
+		if (!rval && subdev == &sensor->src->sd) {
+			csi_format = smiapp_validate_csi_data_format(
+				sensor, fmt->format.code);
+			if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+				sensor->csi_format = csi_format;
+			fmt->format.code = csi_format->code;
+		}
+
+		mutex_unlock(&sensor->mutex);
+		return rval;
+	}
+
+	/* Sink pad. Width and height are changeable here. */
+	fmt->format.code = __smiapp_get_mbus_code(subdev, fmt->pad);
+	fmt->format.width &= ~1;
+	fmt->format.height &= ~1;
+
+	fmt->format.width =
+		clamp(fmt->format.width,
+		      sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
+		      sensor->limits[SMIAPP_LIMIT_MAX_X_OUTPUT_SIZE]);
+	fmt->format.height =
+		clamp(fmt->format.height,
+		      sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],
+		      sensor->limits[SMIAPP_LIMIT_MAX_Y_OUTPUT_SIZE]);
+
+	smiapp_get_crop_compose(subdev, fh, crops, NULL, fmt->which);
+
+	crops[ssd->sink_pad]->left = 0;
+	crops[ssd->sink_pad]->top = 0;
+	crops[ssd->sink_pad]->width = fmt->format.width;
+	crops[ssd->sink_pad]->height = fmt->format.height;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+		ssd->sink_fmt = *crops[ssd->sink_pad];
+	smiapp_propagate(subdev, fh, fmt->which,
+			 V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL);
+
+	mutex_unlock(&sensor->mutex);
+
+	return 0;
+}
Signature · 3 lines
Regards,

Laurent Pinchart
#86 lore raw

Re: [PATCH v5.3 35/35] smiapp: Add driver

Hi Laurent,

Thanks for the comments!

Quoted 22 lines · Laurent Pinchart
Quoted 10 lines · On Thursday 08 March 2012 18:49:43 Sakari Ailus wrote:

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.

[snip]

Quoted 8 lines
(quoted diff) +0 -0

b/drivers/media/video/smiapp-pll.c index be63bb4..326bd0e 100644

drivers/media/video/smiapp-pll.c +0 -0
@@ -22,6 +22,8 @@
   *
   */
 
Quoted 4 lines

drivers/media/video/smiapp-pll.c line 26

Quoted 2 lines
drivers/media/video/smiapp-pll.c +2 -0
+#include "smiapp/smiapp-debug.h"
+

Is this needed ?

If debugging is enabled for SMIA++ driver the same is done for the PLL code. It's the only driver using the PLL code currently and I think it's an appropriate way to enable debug output.

I expect this to be changed in the future though.

What do you think? Would you only rely on dynamic printk?

Quoted 25 lines

drivers/media/video/smiapp-pll.c line 29

Quoted 3 lines
drivers/media/video/smiapp-pll.c +0 -0
  #include<linux/gcd.h>
  #include<linux/lcm.h>
  #include<linux/module.h>

[snio]

Quoted 5 lines
(quoted diff) +0 -0

b/drivers/media/video/smiapp/smiapp-core.c new file mode 100644 index 0000000..68f4397

drivers/media/video/smiapp/smiapp-core.c new file +0 -0

[snip]

Quoted 11 lines
drivers/media/video/smiapp/smiapp-core.c new file +11 -0
+static int smiapp_set_format(struct v4l2_subdev *subdev,
+			     struct v4l2_subdev_fh *fh,
+			     struct v4l2_subdev_format *fmt)
+{
+	struct smiapp_sensor *sensor = to_smiapp_sensor(subdev);
+	struct smiapp_subdev *ssd = to_smiapp_subdev(subdev);
+	struct v4l2_rect *crops[SMIAPP_PADS];
+	const struct smiapp_csi_data_format *csi_format;
+
+	mutex_lock(&sensor->mutex);
+
Quoted 8 lines

drivers/media/video/smiapp/smiapp-core.c line 1661

Quoted 6 lines
drivers/media/video/smiapp/smiapp-core.c new file +6 -0
+	/*
+	 * Media bus code is changeable on src subdev's source pad. On
+	 * other source pads we just get format here.
+	 */
+	if (fmt->pad == ssd->source_pad) {
+		int rval = __smiapp_get_format(subdev, fh, fmt);

This overwrites fmt completely, you won't be able to change it at all.

Good catch. I'll fix it and resend.

Quoted 33 lines
Quoted 33 lines
drivers/media/video/smiapp/smiapp-core.c new file +33 -0
+		if (!rval&&  subdev ==&sensor->src->sd) {
+			csi_format = smiapp_validate_csi_data_format(
+				sensor, fmt->format.code);
+			if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
+				sensor->csi_format = csi_format;
+			fmt->format.code = csi_format->code;
+		}
+
+		mutex_unlock(&sensor->mutex);
+		return rval;
+	}
+
+	/* Sink pad. Width and height are changeable here. */
+	fmt->format.code = __smiapp_get_mbus_code(subdev, fmt->pad);
+	fmt->format.width&= ~1;
+	fmt->format.height&= ~1;
+
+	fmt->format.width =
+		clamp(fmt->format.width,
+		      sensor->limits[SMIAPP_LIMIT_MIN_X_OUTPUT_SIZE],
+		      sensor->limits[SMIAPP_LIMIT_MAX_X_OUTPUT_SIZE]);
+	fmt->format.height =
+		clamp(fmt->format.height,
+		      sensor->limits[SMIAPP_LIMIT_MIN_Y_OUTPUT_SIZE],
+		      sensor->limits[SMIAPP_LIMIT_MAX_Y_OUTPUT_SIZE]);
+
+	smiapp_get_crop_compose(subdev, fh, crops, NULL, fmt->which);
+
+	crops[ssd->sink_pad]->left = 0;
+	crops[ssd->sink_pad]->top = 0;
+	crops[ssd->sink_pad]->width = fmt->format.width;
+	crops[ssd->sink_pad]->height = fmt->format.height;
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE)
Quoted 9 lines

drivers/media/video/smiapp/smiapp-core.c line 1702

Quoted 8 lines
drivers/media/video/smiapp/smiapp-core.c new file +8 -0
+		ssd->sink_fmt = *crops[ssd->sink_pad];
+	smiapp_propagate(subdev, fh, fmt->which,
+			 V4L2_SUBDEV_SEL_TGT_CROP_ACTUAL);
+
+	mutex_unlock(&sensor->mutex);
+
+	return 0;
+}

Regards,

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

PATCH v5 35/35 smiapp: Add driver

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                  |    2 +
 drivers/media/video/Makefile                 |    1 +
 drivers/media/video/smiapp-pll.c             |    2 +
 drivers/media/video/smiapp/Kconfig           |   13 +
 drivers/media/video/smiapp/Makefile          |    3 +
 drivers/media/video/smiapp/smiapp-core.c     | 2832 ++++++++++++++++++++++++++
 drivers/media/video/smiapp/smiapp-debug.h    |   32 +
 drivers/media/video/smiapp/smiapp-limits.c   |  132 ++
 drivers/media/video/smiapp/smiapp-limits.h   |  128 ++
 drivers/media/video/smiapp/smiapp-quirk.c    |  264 +++
 drivers/media/video/smiapp/smiapp-quirk.h    |   72 +
 drivers/media/video/smiapp/smiapp-reg-defs.h |  503 +++++
 drivers/media/video/smiapp/smiapp-reg.h      |  122 ++
 drivers/media/video/smiapp/smiapp-regs.c     |  213 ++
 drivers/media/video/smiapp/smiapp-regs.h     |   46 +
 drivers/media/video/smiapp/smiapp.h          |  251 +++
 include/media/smiapp.h                       |   83 +
 17 files changed, 4699 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/smiapp/Kconfig
 create mode 100644 drivers/media/video/smiapp/Makefile
 create mode 100644 drivers/media/video/smiapp/smiapp-core.c
 create mode 100644 drivers/media/video/smiapp/smiapp-debug.h
 create mode 100644 drivers/media/video/smiapp/smiapp-limits.c
 create mode 100644 drivers/media/video/smiapp/smiapp-limits.h
 create mode 100644 drivers/media/video/smiapp/smiapp-quirk.c
 create mode 100644 drivers/media/video/smiapp/smiapp-quirk.h
 create mode 100644 drivers/media/video/smiapp/smiapp-reg-defs.h
 create mode 100644 drivers/media/video/smiapp/smiapp-reg.h
 create mode 100644 drivers/media/video/smiapp/smiapp-regs.c
 create mode 100644 drivers/media/video/smiapp/smiapp-regs.h
 create mode 100644 drivers/media/video/smiapp/smiapp.h
 create mode 100644 include/media/smiapp.h
drivers/media/video/Kconfig +2 -0
index bb89f8c..6569b8e 100644
@@ -527,6 +527,8 @@ 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.
 
+source "drivers/media/video/smiapp/Kconfig"
+
 comment "Flash devices"
 
 config VIDEO_ADP1653
drivers/media/video/Makefile +1 -0
index f184f1d..7b1393d 100644
@@ -73,6 +73,7 @@ obj-$(CONFIG_VIDEO_SR030PC30)	+= sr030pc30.o
 obj-$(CONFIG_VIDEO_NOON010PC30)	+= noon010pc30.o
 obj-$(CONFIG_VIDEO_M5MOLS)	+= m5mols/
 obj-$(CONFIG_VIDEO_S5K6AA)	+= s5k6aa.o
+obj-$(CONFIG_VIDEO_SMIAPP)	+= smiapp/
 obj-$(CONFIG_VIDEO_ADP1653)	+= adp1653.o
 obj-$(CONFIG_VIDEO_AS3645A)	+= as3645a.o
 
drivers/media/video/smiapp-pll.c +2 -0
index be63bb4..326bd0e 100644
@@ -22,6 +22,8 @@
  *
  */
 
+#include "smiapp/smiapp-debug.h"
+
 #include <linux/gcd.h>
 #include <linux/lcm.h>
 #include <linux/module.h>
drivers/media/video/smiapp/Kconfig new file +13 -0
new file mode 100644
index 0000000..9504c43
@@ -0,0 +1,13 @@
+config VIDEO_SMIAPP
+	tristate "SMIA++/SMIA sensor support"
+	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
+	select VIDEO_SMIAPP_PLL
+	---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.
drivers/media/video/smiapp/Makefile new file +3 -0
new file mode 100644
index 0000000..5a207ee
@@ -0,0 +1,3 @@
+smiapp-objs			+= smiapp-core.o smiapp-regs.o \
+				   smiapp-quirk.o smiapp-limits.o
+obj-$(CONFIG_VIDEO_SMIAPP)	+= smiapp.o
drivers/media/video/smiapp/smiapp-core.c new file +2832 -0

2,832 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-debug.h new file +32 -0
new file mode 100644
index 0000000..627809e
@@ -0,0 +1,32 @@
+/*
+ * drivers/media/video/smiapp/smiapp-debug.h
+ *
+ * Generic driver for SMIA/SMIA++ compliant camera modules
+ *
+ * Copyright (C) 2011--2012 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/smiapp-limits.c new file +132 -0

97 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-limits.h new file +128 -0

128 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-quirk.c new file +264 -0

264 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-quirk.h new file +72 -0

72 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-reg-defs.h new file +503 -0

503 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-reg.h new file +122 -0

122 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-regs.c new file +213 -0

213 lines not on this page · raw message

drivers/media/video/smiapp/smiapp-regs.h new file +46 -0

46 lines not on this page · raw message

drivers/media/video/smiapp/smiapp.h new file +251 -0

251 lines not on this page · raw message

include/media/smiapp.h new file +83 -0

83 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.

maintainer Acked-by on v5 35/35
#88 lore raw

Re: [PATCH v5.4 35/35] smiapp: Add driver

Hi Sakari,

Quoted 10 lines · On Sunday 11 March 2012 16:45:56 Sakari Ailus wrote:

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.

Signature · 3 lines
Regards,

Laurent Pinchart
#89 lore raw

Re: [PATCH v5.1 35/35] smiapp: Add driver

In reply to Sakari Ailus
Quoted 9 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.

Quoted 5 lines

+       case V4L2_CID_EXPOSURE:
+               return smiapp_write(
+                       client,
+                       SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val); +

At this point, knowing pixel clock and line length, it is possible to get / set the exposure in useconds or millisecond value.

Quoted 1 line

From userspace, if for example you change the format and crop,

you can just set the expo to a value in msec or usec, and get the same exposure after your format change.

The driver is IMO the place where we have all the info. Here is some example code with usec. (The 522 constant is the fine integration register...)

static int mt9j_expo_to_shutter(struct usb_ovfx2 * ov, u32 expo)

{
	int rc = 0;
	u32 expo_pix; // exposition in pixclk unit
	u16 coarse_expo;
	u16 row_time;
	expo_pix = expo * 96;   /// pixel clock in MHz
	MT9J_RREAD(ov, LINE_LENGTH_PCK, &row_time);
	expo_pix = expo_pix - 522;
	coarse_expo = (expo_pix + row_time/2)/ row_time;
	MT9J_RWRITE(ov, COARSE_EXPO_REG, coarse_expo);
	return rc;
}

static int mt9j_shutter_to_expo(struct usb_ovfx2 * ov, u32 * expo)

{
	int rc = 0;
	u32 expo_pix; // exposition in pixclk unit
	u16 coarse_expo;
	u16 row_time;
	MT9J_RREAD(ov, LINE_LENGTH_PCK, &row_time);
	MT9J_RREAD(ov, COARSE_EXPO_REG, &coarse_expo);
	expo_pix = row_time * coarse_expo + 522;
	*expo = expo_pix / (96);
	return rc;
}

Maybe you have enough on your plate for now, and this can wait after inclusion, but it is a nice abstraction to have from userspace point of view.

#90 lore raw

Re: [PATCH v5.1 35/35] smiapp: Add driver

Hi François,

Quoted 10 lines · jean-philippe francois
Quoted 9 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.

Quoted 7 lines
Quoted 5 lines

+       case V4L2_CID_EXPOSURE:
+               return smiapp_write(
+                       client,
+                       SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val); +

At this point, knowing pixel clock and line length, it is possible to get / set the exposure in useconds or millisecond value.

It is possible, but still I don't think we even want that at this level. This is a fairly low level interface.

The exposure time in seconds can always be constructed from horizontal and vertical blanking and the pixel rate in the user space.

How you choose the exposure value in seconds does contain policy decisions which belong to the user space. Sensor drivers don't even have enough information to make these decisions. Providing the exposure time in native unit for sensors allows making these decisions in the user space.

For example:

- To get a common frame rate such as 30 or 25 fps, you need to add blanking, either horizontal or vertical. Using horizontal blanking gives you more unwanted rolling shutter effect but amortises the data rate over time. Which one you want (horizontal or vertical) is dependent on your hardware and what else is involved in your use case

- Hardware limitations. Most blocks in the OMAP 3 ISP have the maximum speed of is 100 Mp/s but for the CSI-2 receiver it's 200 Mp/s. So if the ISP is configured to write the images to memory in the CSI-2 receiver, the maximum pixel rate is 200 Mp/s, not 100. This kind of limitations are quite common in ISPs and not limited to OMAP 3 ISP. Should the sensor driver know which blocks are part of the pipeline, and limit minimum frame time based on that? I admit not everything is in place yet for the full solution of this problem, but making the pixel rate configurable available to the user space is definitely a part of it. Ideally the user should be provided a way to enumerate these limitations to be able to make informed decisions.

It shouldn't be the responsibility of the regular applications to deal with these things, though. We need additional functionality in libv4l2 to provide a higher level interface to the exposure time --- just like for the pipeline configuration. On the other hand, an application tailored to a device must be able to make these decisions by itself.

Quoted 34 lines

From userspace, if for example you change the format and crop, you can just set the expo to a value in msec or usec, and get the same exposure after your format change.

The driver is IMO the place where we have all the info. Here is some example code with usec. (The 522 constant is the fine integration register...)

static int mt9j_expo_to_shutter(struct usb_ovfx2 * ov, u32 expo)

{
	int rc = 0;
	u32 expo_pix; // exposition in pixclk unit
	u16 coarse_expo;
	u16 row_time;
	expo_pix = expo * 96;   /// pixel clock in MHz
	MT9J_RREAD(ov, LINE_LENGTH_PCK, &row_time);
	expo_pix = expo_pix - 522;
	coarse_expo = (expo_pix + row_time/2)/ row_time;
	MT9J_RWRITE(ov, COARSE_EXPO_REG, coarse_expo);
	return rc;
}

static int mt9j_shutter_to_expo(struct usb_ovfx2 * ov, u32 * expo)

{
	int rc = 0;
	u32 expo_pix; // exposition in pixclk unit
	u16 coarse_expo;
	u16 row_time;
	MT9J_RREAD(ov, LINE_LENGTH_PCK, &row_time);
	MT9J_RREAD(ov, COARSE_EXPO_REG, &coarse_expo);
	expo_pix = row_time * coarse_expo + 522;
	*expo = expo_pix / (96);
	return rc;
}
Quoted 3 lines

Maybe you have enough on your plate for now, and this can wait after inclusion, but it is a nice abstraction to have from userspace point of view.

Kind regards,

Signature · 2 lines
Sakari Ailus
e-mail: [email protected]	jabber/XMPP/Gmail: [email protected]
#91 lore raw

Re: [PATCH v5.1 35/35] smiapp: Add driver

Quoted 18 lines · Sakari Ailus

Hi François,

Quoted 15 lines · jean-philippe francois
Quoted 14 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.

+       case V4L2_CID_EXPOSURE:
+               return smiapp_write(
+                       client,
+                       SMIAPP_REG_U16_COARSE_INTEGRATION_TIME, ctrl->val); +

Quoted 9 lines
Quoted 2 lines

At this point, knowing pixel clock and line length, it is possible to get / set the exposure in useconds or millisecond value.

It is possible, but still I don't think we even want that at this level. This is a fairly low level interface.

The exposure time in seconds can always be constructed from horizontal and vertical blanking and the pixel rate in the user space.

I think it is on the side of abstraction, not on the side of policy. If you want to sort this in userspace, then you need to decide on a common unit for the exposure control.

Is it a number of pixel, a number of line, anumber of quarter of line ? If userspace does not know that, then it needs to know which kind of sensor it is driving, and then the driver somehow failed at providing abstraction. And I
should not have to use a library with all the quirks for all the existing sensor out there when it could have been done at the driver level. Modularity is generally lost when you leave the solution to userspace.

I think there are two orthogonal subject here :
-one is abstracting sensor differences, to expose sensor capabilities in a way that is sensible or natural. Wether you set the exposure to 50 msec or 337 "native unit" does not change the fact that it may conflicts with a previous
framerate settings of 1/30 sec, but it is much easier to understand what you do using msec.

- The other subject is how to solve a particular set of constraints with a given set
of conflicting controls. As you pointed it, framerate and exposure can be one of those. Let's suppose the application adjust the framerate, using hblank. Exposure will change as
a consequences . If the application wants to keep the same exposure, it will either
- do sensor dependant computation to compute a new "native unit"
exposure value.
- Set the exposure to it's previous value using "natural, sensor
independent" unit.
In both cases, the exposure unit has no effect on the decision making ability of the
application. In both cases, if the new exposure value is out of range, a decision must be taken
wether framerate should limit exposure or not. And in this particular case, the policy is clearly in
the driver already, since setting vblank determine the exposure setting limits.

So to sum up :
- Exposure control unit has nothing to do with policy, but is rather a matter of useful abstraction
- Conflicting control is another orthogonal problem.

Jean-Philippe François

#92 lore raw

PATCH v5 35/35 rm680: Add camera init

In reply to Sakari Ailus

From: Sakari Ailus <[email protected]>

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 |  375 ++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/board-rm680.c        |   38 +++
 3 files changed, 415 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-omap2/board-rm680-camera.c
arch/arm/mach-omap2/Makefile +2 -1
index fc9b238..f92cc92 100644
@@ -206,7 +206,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 +375 -0

375 lines not on this page · raw message

arch/arm/mach-omap2/board-rm680.c +38 -0
index 8678b38..71607a70 100644
@@ -66,6 +66,39 @@ 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 */
+	REGULATOR_SUPPLY("vaux2", NULL),
+};
+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 */
+	REGULATOR_SUPPLY("vaux3", NULL),
+};
+REGULATOR_INIT_DATA_FIXED(rm680_vaux3, 2800000);
+
 static struct platform_device *rm680_peripherals_devices[] __initdata = {
 	&rm680_vemmc_device,
 };
@@ -82,6 +115,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 +164,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 +178,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 · 1 line
1.7.2.5