bcm27xx: add support for linux v5.15
[openwrt/staging/chunkeey.git] / target / linux / bcm27xx / patches-5.15 / 950-0243-media-irs1125-Keep-HW-in-sync-after-imager-reset.patch
1 From dbabaea748b78ebcd6659168ee8259340da5e8fa Mon Sep 17 00:00:00 2001
2 From: Markus Proeller <markus.proeller@pieye.org>
3 Date: Tue, 16 Jun 2020 13:33:56 +0200
4 Subject: [PATCH] media: irs1125: Keep HW in sync after imager reset
5
6 When closing the video device, the irs1125 is put in power down state.
7 To keep V4L2 ctrls and the HW in sync, v4l2_ctrl_handler_setup is
8 called after power up.
9
10 The compound ctrl IRS1125_CID_MOD_PLL however has a default value
11 of all zeros, which puts the imager into a non responding state.
12 Thus, this ctrl is not written by the driver into HW after power up.
13 The userspace has to take care to write senseful data.
14
15 Signed-off-by: Markus Proeller <markus.proeller@pieye.org>
16 ---
17 drivers/media/i2c/irs1125.c | 121 +++++++++++++++++-------------------
18 1 file changed, 58 insertions(+), 63 deletions(-)
19
20 --- a/drivers/media/i2c/irs1125.c
21 +++ b/drivers/media/i2c/irs1125.c
22 @@ -82,6 +82,7 @@ struct irs1125 {
23 struct v4l2_ctrl *ctrl_numseq;
24
25 int power_count;
26 + bool mod_pll_init;
27 };
28
29 static inline struct irs1125 *to_state(struct v4l2_subdev *sd)
30 @@ -276,8 +277,7 @@ static struct regval_list irs1125_seq_cf
31 {0xC039, 0x0000},
32 {0xC401, 0x0002},
33
34 - {0xFFFF, 1},
35 - {0xA87C, 0x0001}
36 + {0xFFFF, 1}
37 };
38
39 static int irs1125_write(struct v4l2_subdev *sd, u16 reg, u16 val)
40 @@ -471,7 +471,11 @@ static int __sensor_init(struct v4l2_sub
41 return ret;
42 }
43
44 - return 0;
45 + irs1125->mod_pll_init = true;
46 + v4l2_ctrl_handler_setup(&irs1125->ctrl_handler);
47 + irs1125->mod_pll_init = false;
48 +
49 + return irs1125_write(sd, 0xA87C, 0x0001);
50 }
51
52 static int irs1125_sensor_power(struct v4l2_subdev *sd, int on)
53 @@ -607,8 +611,6 @@ static int irs1125_s_ctrl(struct v4l2_ct
54 struct irs1125 *dev = container_of(ctrl->handler,
55 struct irs1125, ctrl_handler);
56 struct i2c_client *client = v4l2_get_subdevdata(&dev->sd);
57 - struct irs1125_mod_pll *mod_cur, *mod_new;
58 - u16 addr, val;
59 int err = 0, i;
60
61 switch (ctrl->id) {
62 @@ -660,68 +662,61 @@ static int irs1125_s_ctrl(struct v4l2_ct
63 ctrl->val);
64 break;
65 }
66 - case IRS1125_CID_MOD_PLL:
67 + case IRS1125_CID_MOD_PLL: {
68 + struct irs1125_mod_pll *mod_new;
69 +
70 + if (dev->mod_pll_init)
71 + break;
72 +
73 mod_new = (struct irs1125_mod_pll *)ctrl->p_new.p;
74 - mod_cur = (struct irs1125_mod_pll *)ctrl->p_cur.p;
75 for (i = 0; i < IRS1125_NUM_MOD_PLLS; i++) {
76 - if (mod_cur[i].pllcfg1 != mod_new[i].pllcfg1) {
77 - addr = 0xC3A0 + i * 3;
78 - val = mod_new[i].pllcfg1;
79 - err = irs1125_write(&dev->sd, addr, val);
80 - if (err < 0)
81 - break;
82 - }
83 - if (mod_cur[i].pllcfg2 != mod_new[i].pllcfg2) {
84 - addr = 0xC3A1 + i * 3;
85 - val = mod_new[i].pllcfg2;
86 - err = irs1125_write(&dev->sd, addr, val);
87 - if (err < 0)
88 - break;
89 - }
90 - if (mod_cur[i].pllcfg3 != mod_new[i].pllcfg3) {
91 - addr = 0xC3A2 + i * 3;
92 - val = mod_new[i].pllcfg3;
93 - err = irs1125_write(&dev->sd, addr, val);
94 - if (err < 0)
95 - break;
96 - }
97 - if (mod_cur[i].pllcfg4 != mod_new[i].pllcfg4) {
98 - addr = 0xC24C + i * 5;
99 - val = mod_new[i].pllcfg4;
100 - err = irs1125_write(&dev->sd, addr, val);
101 - if (err < 0)
102 - break;
103 - }
104 - if (mod_cur[i].pllcfg5 != mod_new[i].pllcfg5) {
105 - addr = 0xC24D + i * 5;
106 - val = mod_new[i].pllcfg5;
107 - err = irs1125_write(&dev->sd, addr, val);
108 - if (err < 0)
109 - break;
110 - }
111 - if (mod_cur[i].pllcfg6 != mod_new[i].pllcfg6) {
112 - addr = 0xC24E + i * 5;
113 - val = mod_new[i].pllcfg6;
114 - err = irs1125_write(&dev->sd, addr, val);
115 - if (err < 0)
116 - break;
117 - }
118 - if (mod_cur[i].pllcfg7 != mod_new[i].pllcfg7) {
119 - addr = 0xC24F + i * 5;
120 - val = mod_new[i].pllcfg7;
121 - err = irs1125_write(&dev->sd, addr, val);
122 - if (err < 0)
123 - break;
124 - }
125 - if (mod_cur[i].pllcfg8 != mod_new[i].pllcfg8) {
126 - addr = 0xC250 + i * 5;
127 - val = mod_new[i].pllcfg8;
128 - err = irs1125_write(&dev->sd, addr, val);
129 - if (err < 0)
130 - break;
131 - }
132 + unsigned int pll_offset, ssc_offset;
133 +
134 + pll_offset = i * 3;
135 + ssc_offset = i * 5;
136 +
137 + err = irs1125_write(&dev->sd, 0xC3A0 + pll_offset,
138 + mod_new[i].pllcfg1);
139 + if (err < 0)
140 + break;
141 +
142 + err = irs1125_write(&dev->sd, 0xC3A1 + pll_offset,
143 + mod_new[i].pllcfg2);
144 + if (err < 0)
145 + break;
146 +
147 + err = irs1125_write(&dev->sd, 0xC3A2 + pll_offset,
148 + mod_new[i].pllcfg3);
149 + if (err < 0)
150 + break;
151 +
152 + err = irs1125_write(&dev->sd, 0xC24C + ssc_offset,
153 + mod_new[i].pllcfg4);
154 + if (err < 0)
155 + break;
156 +
157 + err = irs1125_write(&dev->sd, 0xC24D + ssc_offset,
158 + mod_new[i].pllcfg5);
159 + if (err < 0)
160 + break;
161 +
162 + err = irs1125_write(&dev->sd, 0xC24E + ssc_offset,
163 + mod_new[i].pllcfg6);
164 + if (err < 0)
165 + break;
166 +
167 + err = irs1125_write(&dev->sd, 0xC24F + ssc_offset,
168 + mod_new[i].pllcfg7);
169 + if (err < 0)
170 + break;
171 +
172 + err = irs1125_write(&dev->sd, 0xC250 + ssc_offset,
173 + mod_new[i].pllcfg8);
174 + if (err < 0)
175 + break;
176 }
177 break;
178 + }
179 case IRS1125_CID_SEQ_CONFIG: {
180 struct irs1125_seq_cfg *cfg_new;
181