Skip to content

Commit 2220f29

Browse files
mitaehristev
authored andcommitted
media: ov7670: add V4L2_CID_TEST_PATTERN control
The ov7670 has the test pattern generator features. This makes use of it through V4L2_CID_TEST_PATTERN control. Cc: Jonathan Corbet <corbet@lwn.net> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
1 parent 5c327f0 commit 2220f29

1 file changed

Lines changed: 45 additions & 1 deletion

File tree

drivers/media/i2c/ov7670.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
163163
#define DBLV_X6 0x10 /* clock x6 */
164164
#define DBLV_X8 0x11 /* clock x8 */
165165

166+
#define REG_SCALING_XSC 0x70 /* Test pattern and horizontal scale factor */
167+
#define TEST_PATTTERN_0 0x80
168+
#define REG_SCALING_YSC 0x71 /* Test pattern and vertical scale factor */
169+
#define TEST_PATTTERN_1 0x80
170+
166171
#define REG_REG76 0x76 /* OV's name */
167172
#define R76_BLKPCOR 0x80 /* Black pixel correction enable */
168173
#define R76_WHTPCOR 0x40 /* White pixel correction enable */
@@ -292,7 +297,8 @@ static struct regval_list ov7670_default_regs[] = {
292297

293298
{ REG_COM3, 0 }, { REG_COM14, 0 },
294299
/* Mystery scaling numbers */
295-
{ 0x70, 0x3a }, { 0x71, 0x35 },
300+
{ REG_SCALING_XSC, 0x3a },
301+
{ REG_SCALING_YSC, 0x35 },
296302
{ 0x72, 0x11 }, { 0x73, 0xf0 },
297303
{ 0xa2, 0x02 }, { REG_COM10, 0x0 },
298304

@@ -568,6 +574,19 @@ static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
568574
return ov7670_write_i2c(sd, reg, value);
569575
}
570576

577+
static int ov7670_update_bits(struct v4l2_subdev *sd, unsigned char reg,
578+
unsigned char mask, unsigned char value)
579+
{
580+
unsigned char orig;
581+
int ret;
582+
583+
ret = ov7670_read(sd, reg, &orig);
584+
if (ret)
585+
return ret;
586+
587+
return ov7670_write(sd, reg, (orig & ~mask) | (value & mask));
588+
}
589+
571590
/*
572591
* Write a list of register settings; ff/ff stops the process.
573592
*/
@@ -1470,6 +1489,25 @@ static int ov7670_s_autoexp(struct v4l2_subdev *sd,
14701489
return ret;
14711490
}
14721491

1492+
static const char * const ov7670_test_pattern_menu[] = {
1493+
"No test output",
1494+
"Shifting \"1\"",
1495+
"8-bar color bar",
1496+
"Fade to gray color bar",
1497+
};
1498+
1499+
static int ov7670_s_test_pattern(struct v4l2_subdev *sd, int value)
1500+
{
1501+
int ret;
1502+
1503+
ret = ov7670_update_bits(sd, REG_SCALING_XSC, TEST_PATTTERN_0,
1504+
value & BIT(0) ? TEST_PATTTERN_0 : 0);
1505+
if (ret)
1506+
return ret;
1507+
1508+
return ov7670_update_bits(sd, REG_SCALING_YSC, TEST_PATTTERN_1,
1509+
value & BIT(1) ? TEST_PATTTERN_1 : 0);
1510+
}
14731511

14741512
static int ov7670_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
14751513
{
@@ -1516,6 +1554,8 @@ static int ov7670_s_ctrl(struct v4l2_ctrl *ctrl)
15161554
return ov7670_s_exp(sd, info->exposure->val);
15171555
}
15181556
return ov7670_s_autoexp(sd, ctrl->val);
1557+
case V4L2_CID_TEST_PATTERN:
1558+
return ov7670_s_test_pattern(sd, ctrl->val);
15191559
}
15201560
return -EINVAL;
15211561
}
@@ -1770,6 +1810,10 @@ static int ov7670_probe(struct i2c_client *client,
17701810
info->auto_exposure = v4l2_ctrl_new_std_menu(&info->hdl, &ov7670_ctrl_ops,
17711811
V4L2_CID_EXPOSURE_AUTO, V4L2_EXPOSURE_MANUAL, 0,
17721812
V4L2_EXPOSURE_AUTO);
1813+
v4l2_ctrl_new_std_menu_items(&info->hdl, &ov7670_ctrl_ops,
1814+
V4L2_CID_TEST_PATTERN,
1815+
ARRAY_SIZE(ov7670_test_pattern_menu) - 1, 0, 0,
1816+
ov7670_test_pattern_menu);
17731817
sd->ctrl_handler = &info->hdl;
17741818
if (info->hdl.error) {
17751819
ret = info->hdl.error;

0 commit comments

Comments
 (0)