aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.10/950-0471-Added-hflip-and-vflip-controls-to-ov9281.patch
blob: ded3dce942b8a113ce7fc137759cc21e217364f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
From 6c7ebe661716fc23c52cd800a173e4675b10202a Mon Sep 17 00:00:00 2001
From: Mathias Anhalt <mathiasanhalt@web.de>
Date: Wed, 3 Feb 2021 20:34:09 +0100
Subject: [PATCH] Added hflip and vflip controls to ov9281

Signed-off-by: Mathias Anhalt <mathiasanhalt@web.de>
---
 drivers/media/i2c/ov9281.c | 58 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

--- a/drivers/media/i2c/ov9281.c
+++ b/drivers/media/i2c/ov9281.c
@@ -40,6 +40,10 @@
 #define CHIP_ID				0x9281
 #define OV9281_REG_CHIP_ID		0x300a
 
+#define OV9281_REG_TIMING_FORMAT_1		0x3820
+#define OV9281_REG_TIMING_FORMAT_2		0x3821
+#define OV9281_FLIP_BIT				BIT(2)
+
 #define OV9281_REG_CTRL_MODE		0x0100
 #define OV9281_MODE_SW_STANDBY		0x0
 #define OV9281_MODE_STREAMING		BIT(0)
@@ -123,6 +127,8 @@ struct ov9281 {
 	struct v4l2_ctrl	*digi_gain;
 	struct v4l2_ctrl	*hblank;
 	struct v4l2_ctrl	*vblank;
+	struct v4l2_ctrl	*hflip;
+	struct v4l2_ctrl	*vflip;
 	struct v4l2_ctrl	*pixel_rate;
 	struct v4l2_ctrl	*test_pattern;
 	struct mutex		mutex;
@@ -615,6 +621,42 @@ static int ov9281_enable_test_pattern(st
 				OV9281_REG_VALUE_08BIT, val);
 }
 
+static int ov9281_set_ctrl_hflip(struct ov9281 *ov9281, int value)
+{
+	u32 current_val;
+	int ret = ov9281_read_reg(ov9281->client, OV9281_REG_TIMING_FORMAT_2,
+					OV9281_REG_VALUE_08BIT, &current_val);
+	if (!ret) {
+		if (value)
+			current_val |= OV9281_FLIP_BIT;
+		else
+			current_val &= ~OV9281_FLIP_BIT;
+		return ov9281_write_reg(ov9281->client,
+						OV9281_REG_TIMING_FORMAT_2,
+						OV9281_REG_VALUE_08BIT,
+						current_val);
+	}
+	return ret;
+}
+
+static int ov9281_set_ctrl_vflip(struct ov9281 *ov9281, int value)
+{
+	u32 current_val;
+	int ret = ov9281_read_reg(ov9281->client, OV9281_REG_TIMING_FORMAT_1,
+					OV9281_REG_VALUE_08BIT, &current_val);
+	if (!ret) {
+		if (value)
+			current_val |= OV9281_FLIP_BIT;
+		else
+			current_val &= ~OV9281_FLIP_BIT;
+		return ov9281_write_reg(ov9281->client,
+						OV9281_REG_TIMING_FORMAT_1,
+						OV9281_REG_VALUE_08BIT,
+						current_val);
+	}
+	return ret;
+}
+
 static const struct v4l2_rect *
 __ov9281_get_pad_crop(struct ov9281 *ov9281, struct v4l2_subdev_pad_config *cfg,
 		      unsigned int pad, enum v4l2_subdev_format_whence which)
@@ -933,6 +975,12 @@ static int ov9281_set_ctrl(struct v4l2_c
 		return 0;
 
 	switch (ctrl->id) {
+	case V4L2_CID_HFLIP:
+		ret = ov9281_set_ctrl_hflip(ov9281, ctrl->val);
+		break;
+	case V4L2_CID_VFLIP:
+		ret = ov9281_set_ctrl_vflip(ov9281, ctrl->val);
+		break;
 	case V4L2_CID_EXPOSURE:
 		/* 4 least significant bits of expsoure are fractional part */
 		ret = ov9281_write_reg(ov9281->client, OV9281_REG_EXPOSURE,
@@ -981,7 +1029,7 @@ static int ov9281_initialize_controls(st
 
 	handler = &ov9281->ctrl_handler;
 	mode = ov9281->cur_mode;
-	ret = v4l2_ctrl_handler_init(handler, 8);
+	ret = v4l2_ctrl_handler_init(handler, 9);
 	if (ret)
 		return ret;
 	handler->lock = &ov9281->mutex;
@@ -1022,6 +1070,14 @@ static int ov9281_initialize_controls(st
 					      OV9281_GAIN_STEP,
 					      OV9281_GAIN_DEFAULT);
 
+	ov9281->vflip = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops,
+					  V4L2_CID_VFLIP,
+						0, 1, 1, 0);
+
+	ov9281->hflip = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops,
+					  V4L2_CID_HFLIP,
+						0, 1, 1, 0);
+
 	ov9281->test_pattern =
 		v4l2_ctrl_new_std_menu_items(handler, &ov9281_ctrl_ops,
 					     V4L2_CID_TEST_PATTERN,