[v2,11/11] mt9m111: make use of testpattern

Message ID 1280833069-26993-12-git-send-email-m.grzeschik@pengutronix.de (mailing list archive)
State Superseded, archived
Headers

Commit Message

Michael Grzeschik Aug. 3, 2010, 10:57 a.m. UTC
  Signed-off-by: Philipp Wiesner <p.wiesner@phytec.de>
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
Changes v1 -> v2
	* removed ifdef DEBUG

 drivers/media/video/mt9m111.c |   57 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 57 insertions(+), 0 deletions(-)
  

Comments

Robert Jarzmik Aug. 29, 2010, 4:57 p.m. UTC | #1
Michael Grzeschik <m.grzeschik@pengutronix.de> writes:

> Signed-off-by: Philipp Wiesner <p.wiesner@phytec.de>
> Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>

I would require a small change here.

I am using the testpattern for non regression tests. This change implies that
the test pattern can only be set up by module parameters, and blocks the usage
through V4L2 debug, registers, see below:
        memset(&set_reg, 0, sizeof(set_reg));
        set_reg.match.type = V4L2_CHIP_MATCH_I2C_ADDR;
        set_reg.match.addr = 0x5d;
        set_reg.reg = 0x148;
        set_reg.val = test_pattern;
        set_reg.size = 1;
        if (test_pattern != -1)
                if (-1 == xioctl (fd, VIDIOC_DBG_S_REGISTER, &set_reg)) {
                        fprintf (stderr, "%s could set test pattern %x\n",
                                 dev_name, test_pattern);
                        exit (EXIT_FAILURE);
                }

But, the idea is not bad. Therefore, I'd like you to change:
> +	dev_dbg(&client->dev, "%s: using testpattern %d\n", __func__,
> +			testpattern);
> +
> +	if (!ret)
> +		ret = mt9m111_reg_set(client,
> +				MT9M111_TEST_PATTERN_GEN, pattern);
into
> +	dev_dbg(&client->dev, "%s: using testpattern %d\n", __func__,
> +			testpattern);
> +
> +	if (!ret && pattern)
> +		ret = mt9m111_reg_set(client,
> +				MT9M111_TEST_PATTERN_GEN, pattern);
> +

This way, the V4L2 debug registers usage is still allowed, and your module
parameter works too.

Cheers.

--
Robert
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  
Guennadi Liakhovetski Aug. 29, 2010, 6:35 p.m. UTC | #2
On Sun, 29 Aug 2010, Robert Jarzmik wrote:

> Michael Grzeschik <m.grzeschik@pengutronix.de> writes:
> 
> > Signed-off-by: Philipp Wiesner <p.wiesner@phytec.de>
> > Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
> 
> I would require a small change here.
> 
> I am using the testpattern for non regression tests. This change implies that
> the test pattern can only be set up by module parameters, and blocks the usage
> through V4L2 debug, registers, see below:
>         memset(&set_reg, 0, sizeof(set_reg));
>         set_reg.match.type = V4L2_CHIP_MATCH_I2C_ADDR;
>         set_reg.match.addr = 0x5d;
>         set_reg.reg = 0x148;
>         set_reg.val = test_pattern;
>         set_reg.size = 1;
>         if (test_pattern != -1)
>                 if (-1 == xioctl (fd, VIDIOC_DBG_S_REGISTER, &set_reg)) {
>                         fprintf (stderr, "%s could set test pattern %x\n",
>                                  dev_name, test_pattern);
>                         exit (EXIT_FAILURE);
>                 }
> 
> But, the idea is not bad. Therefore, I'd like you to change:
> > +	dev_dbg(&client->dev, "%s: using testpattern %d\n", __func__,
> > +			testpattern);
> > +
> > +	if (!ret)
> > +		ret = mt9m111_reg_set(client,
> > +				MT9M111_TEST_PATTERN_GEN, pattern);
> into
> > +	dev_dbg(&client->dev, "%s: using testpattern %d\n", __func__,
> > +			testpattern);
> > +
> > +	if (!ret && pattern)
> > +		ret = mt9m111_reg_set(client,
> > +				MT9M111_TEST_PATTERN_GEN, pattern);
> > +
> 
> This way, the V4L2 debug registers usage is still allowed, and your module
> parameter works too.

Yes, but this has another disadvantage - if you do not use s_register / 
g_register, maybe you just have CONFIG_VIDEO_ADV_DEBUG off, then, once you 
load the module with the testpattern parameter, you cannot switch using 
testpatterns off again (without a reboot or a power cycle). With the 
original version you can load the driver with the parameter set, then 
unload it, load it without the parameter and testpattern would be cleared. 
In general, I think, using direct register access is discouraged, 
especially if there's a way to set the same functionality using driver's 
supported interfaces. Hm, if I'm not mistaken, it has once been mentioned, 
that these test-patterns can be nicely implemented using the S_INPUT 
ioctl(). Am I right? How about that? But we'd need a confirmation for 
that, I'm not 100% sure.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
  
Robert Jarzmik Sept. 5, 2010, 4:44 p.m. UTC | #3
Guennadi Liakhovetski <g.liakhovetski@gmx.de> writes:

> Yes, but this has another disadvantage - if you do not use s_register / 
> g_register, maybe you just have CONFIG_VIDEO_ADV_DEBUG off, then, once you 
> load the module with the testpattern parameter, you cannot switch using 
> testpatterns off again (without a reboot or a power cycle). With the 
> original version you can load the driver with the parameter set, then 
> unload it, load it without the parameter and testpattern would be cleared. 
> In general, I think, using direct register access is discouraged, 
> especially if there's a way to set the same functionality using driver's 
> supported interfaces.

I agree. If there is a way without debug registers, let's use it.

> Hm, if I'm not mistaken, it has once been mentioned, that these test-patterns
> can be nicely implemented using the S_INPUT ioctl(). Am I right? How about
> that? But we'd need a confirmation for that, I'm not 100% sure.
I can't remember that. But if there is a standard ioctl (as seems to show
videodev2.h), and that its use could mean "camera's input is a testpattern" or
"camera input is the normal optical flow", then we should use it.
If not, the old way with debug registers is the only alternative I see without
having to unload/reload the module (if it's a module and not statically embedded
in the kernel).

Cheers.

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

Patch

diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 25b2317..e1b2d33 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -87,6 +87,7 @@ 
  */
 #define MT9M111_OPER_MODE_CTRL		0x106
 #define MT9M111_OUTPUT_FORMAT_CTRL	0x108
+#define MT9M111_TEST_PATTERN_GEN	0x148
 #define MT9M111_REDUCER_XZOOM_B		0x1a0
 #define MT9M111_REDUCER_XSIZE_B		0x1a1
 #define MT9M111_REDUCER_YZOOM_B		0x1a3
@@ -103,6 +104,15 @@ 
 #define MT9M111_OPMODE_AUTOWHITEBAL_EN	(1 << 1)
 #define MT9M111_OUTFMT_FLIP_BAYER_COL  (1 << 9)
 #define MT9M111_OUTFMT_FLIP_BAYER_ROW  (1 << 8)
+#define MT9M111_TST_PATT_OFF		(0 << 0)
+#define MT9M111_TST_PATT_1		(1 << 0)
+#define MT9M111_TST_PATT_2		(2 << 0)
+#define MT9M111_TST_PATT_3		(3 << 0)
+#define MT9M111_TST_PATT_4		(4 << 0)
+#define MT9M111_TST_PATT_5		(5 << 0)
+#define MT9M111_TST_PATT_6		(6 << 0)
+#define MT9M111_TST_PATT_COLORBARS	(7 << 0)
+#define MT9M111_TST_PATT_FORCE_WB_GAIN_1 (1 << 7)
 #define MT9M111_OUTFMT_PROCESSED_BAYER	(1 << 14)
 #define MT9M111_OUTFMT_BYPASS_IFP	(1 << 10)
 #define MT9M111_OUTFMT_INV_PIX_CLOCK	(1 << 9)
@@ -138,6 +148,11 @@ 
 #define MT9M111_MAX_HEIGHT	1024
 #define MT9M111_MAX_WIDTH	1280
 
+static int testpattern;
+module_param(testpattern, int, S_IRUGO);
+MODULE_PARM_DESC(testpattern, "Test pattern: a number from 1 to 10, 0 for "
+		"normal usage");
+
 /* MT9M111 has only one fixed colorspace per pixelcode */
 struct mt9m111_datafmt {
 	enum v4l2_mbus_pixelcode	code;
@@ -459,6 +474,7 @@  static int mt9m111_set_pixfmt(struct i2c_client *client,
 			      enum v4l2_mbus_pixelcode code)
 {
 	u16 data_outfmt1 = 0, data_outfmt2 = 0, mask_outfmt1, mask_outfmt2;
+	u16 pattern = 0;
 	int ret;
 
 	switch (code) {
@@ -525,6 +541,47 @@  static int mt9m111_set_pixfmt(struct i2c_client *client,
 
 	ret = reg_mask(OUTPUT_FORMAT_CTRL, data_outfmt1, mask_outfmt1);
 
+	switch (testpattern) {
+	case 1:
+		pattern = MT9M111_TST_PATT_1 | MT9M111_TST_PATT_FORCE_WB_GAIN_1;
+		break;
+	case 2:
+		pattern = MT9M111_TST_PATT_2 | MT9M111_TST_PATT_FORCE_WB_GAIN_1;
+		break;
+	case 3:
+		pattern = MT9M111_TST_PATT_3 | MT9M111_TST_PATT_FORCE_WB_GAIN_1;
+		break;
+	case 4:
+		pattern = MT9M111_TST_PATT_4 | MT9M111_TST_PATT_FORCE_WB_GAIN_1;
+		break;
+	case 5:
+		pattern = MT9M111_TST_PATT_5 | MT9M111_TST_PATT_FORCE_WB_GAIN_1;
+		break;
+	case 6:
+		pattern = MT9M111_TST_PATT_6 | MT9M111_TST_PATT_FORCE_WB_GAIN_1;
+		break;
+	case 7:
+		pattern = MT9M111_TST_PATT_COLORBARS |
+			MT9M111_TST_PATT_FORCE_WB_GAIN_1;
+		break;
+	case 8:
+		data_outfmt2 |= MT9M111_OUTFMT_TST_RAMP_COL;
+		break;
+	case 9:
+		data_outfmt2 |= MT9M111_OUTFMT_TST_RAMP_ROW;
+		break;
+	case 10:
+		data_outfmt2 |= MT9M111_OUTFMT_TST_RAMP_FRAME;
+		break;
+	}
+
+	dev_dbg(&client->dev, "%s: using testpattern %d\n", __func__,
+			testpattern);
+
+	if (!ret)
+		ret = mt9m111_reg_set(client,
+				MT9M111_TEST_PATTERN_GEN, pattern);
+
 	if (!ret)
 		ret = reg_mask(OUTPUT_FORMAT_CTRL2_A, data_outfmt2,
 			mask_outfmt2);