1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * A V4L2 driver for OmniVision OV5647 cameras. |
4 | * |
5 | * Based on Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor driver |
6 | * Copyright (C) 2011 Sylwester Nawrocki <s.nawrocki@samsung.com> |
7 | * |
8 | * Based on Omnivision OV7670 Camera Driver |
9 | * Copyright (C) 2006-7 Jonathan Corbet <corbet@lwn.net> |
10 | * |
11 | * Copyright (C) 2016, Synopsys, Inc. |
12 | */ |
13 | |
14 | #include <linux/clk.h> |
15 | #include <linux/delay.h> |
16 | #include <linux/gpio/consumer.h> |
17 | #include <linux/i2c.h> |
18 | #include <linux/init.h> |
19 | #include <linux/io.h> |
20 | #include <linux/module.h> |
21 | #include <linux/of_graph.h> |
22 | #include <linux/pm_runtime.h> |
23 | #include <linux/slab.h> |
24 | #include <linux/videodev2.h> |
25 | #include <media/v4l2-ctrls.h> |
26 | #include <media/v4l2-device.h> |
27 | #include <media/v4l2-event.h> |
28 | #include <media/v4l2-fwnode.h> |
29 | #include <media/v4l2-image-sizes.h> |
30 | #include <media/v4l2-mediabus.h> |
31 | |
32 | /* |
33 | * From the datasheet, "20ms after PWDN goes low or 20ms after RESETB goes |
34 | * high if reset is inserted after PWDN goes high, host can access sensor's |
35 | * SCCB to initialize sensor." |
36 | */ |
37 | #define PWDN_ACTIVE_DELAY_MS 20 |
38 | |
39 | #define MIPI_CTRL00_CLOCK_LANE_GATE BIT(5) |
40 | #define MIPI_CTRL00_LINE_SYNC_ENABLE BIT(4) |
41 | #define MIPI_CTRL00_BUS_IDLE BIT(2) |
42 | #define MIPI_CTRL00_CLOCK_LANE_DISABLE BIT(0) |
43 | |
44 | #define OV5647_SW_STANDBY 0x0100 |
45 | #define OV5647_SW_RESET 0x0103 |
46 | #define OV5647_REG_CHIPID_H 0x300a |
47 | #define OV5647_REG_CHIPID_L 0x300b |
48 | #define OV5640_REG_PAD_OUT 0x300d |
49 | #define OV5647_REG_EXP_HI 0x3500 |
50 | #define OV5647_REG_EXP_MID 0x3501 |
51 | #define OV5647_REG_EXP_LO 0x3502 |
52 | #define OV5647_REG_AEC_AGC 0x3503 |
53 | #define OV5647_REG_GAIN_HI 0x350a |
54 | #define OV5647_REG_GAIN_LO 0x350b |
55 | #define OV5647_REG_VTS_HI 0x380e |
56 | #define OV5647_REG_VTS_LO 0x380f |
57 | #define OV5647_REG_FRAME_OFF_NUMBER 0x4202 |
58 | #define OV5647_REG_MIPI_CTRL00 0x4800 |
59 | #define OV5647_REG_MIPI_CTRL14 0x4814 |
60 | #define OV5647_REG_AWB 0x5001 |
61 | #define OV5647_REG_ISPCTRL3D 0x503d |
62 | |
63 | #define REG_TERM 0xfffe |
64 | #define VAL_TERM 0xfe |
65 | #define REG_DLY 0xffff |
66 | |
67 | /* OV5647 native and active pixel array size */ |
68 | #define OV5647_NATIVE_WIDTH 2624U |
69 | #define OV5647_NATIVE_HEIGHT 1956U |
70 | |
71 | #define OV5647_PIXEL_ARRAY_LEFT 16U |
72 | #define OV5647_PIXEL_ARRAY_TOP 16U |
73 | #define OV5647_PIXEL_ARRAY_WIDTH 2592U |
74 | #define OV5647_PIXEL_ARRAY_HEIGHT 1944U |
75 | |
76 | #define OV5647_VBLANK_MIN 4 |
77 | #define OV5647_VTS_MAX 32767 |
78 | |
79 | #define OV5647_EXPOSURE_MIN 4 |
80 | #define OV5647_EXPOSURE_STEP 1 |
81 | #define OV5647_EXPOSURE_DEFAULT 1000 |
82 | #define OV5647_EXPOSURE_MAX 65535 |
83 | |
84 | struct regval_list { |
85 | u16 addr; |
86 | u8 data; |
87 | }; |
88 | |
89 | struct ov5647_mode { |
90 | struct v4l2_mbus_framefmt format; |
91 | struct v4l2_rect crop; |
92 | u64 pixel_rate; |
93 | int hts; |
94 | int vts; |
95 | const struct regval_list *reg_list; |
96 | unsigned int num_regs; |
97 | }; |
98 | |
99 | struct ov5647 { |
100 | struct v4l2_subdev sd; |
101 | struct media_pad pad; |
102 | struct mutex lock; |
103 | struct clk *xclk; |
104 | struct gpio_desc *pwdn; |
105 | bool clock_ncont; |
106 | struct v4l2_ctrl_handler ctrls; |
107 | const struct ov5647_mode *mode; |
108 | struct v4l2_ctrl *pixel_rate; |
109 | struct v4l2_ctrl *hblank; |
110 | struct v4l2_ctrl *vblank; |
111 | struct v4l2_ctrl *exposure; |
112 | }; |
113 | |
114 | static inline struct ov5647 *to_sensor(struct v4l2_subdev *sd) |
115 | { |
116 | return container_of(sd, struct ov5647, sd); |
117 | } |
118 | |
119 | static const char * const [] = { |
120 | "Disabled" , |
121 | "Color Bars" , |
122 | "Color Squares" , |
123 | "Random Data" , |
124 | }; |
125 | |
126 | static const u8 ov5647_test_pattern_val[] = { |
127 | 0x00, /* Disabled */ |
128 | 0x80, /* Color Bars */ |
129 | 0x82, /* Color Squares */ |
130 | 0x81, /* Random Data */ |
131 | }; |
132 | |
133 | static const struct regval_list sensor_oe_disable_regs[] = { |
134 | {0x3000, 0x00}, |
135 | {0x3001, 0x00}, |
136 | {0x3002, 0x00}, |
137 | }; |
138 | |
139 | static const struct regval_list sensor_oe_enable_regs[] = { |
140 | {0x3000, 0x0f}, |
141 | {0x3001, 0xff}, |
142 | {0x3002, 0xe4}, |
143 | }; |
144 | |
145 | static struct regval_list ov5647_2592x1944_10bpp[] = { |
146 | {0x0100, 0x00}, |
147 | {0x0103, 0x01}, |
148 | {0x3034, 0x1a}, |
149 | {0x3035, 0x21}, |
150 | {0x3036, 0x69}, |
151 | {0x303c, 0x11}, |
152 | {0x3106, 0xf5}, |
153 | {0x3821, 0x06}, |
154 | {0x3820, 0x00}, |
155 | {0x3827, 0xec}, |
156 | {0x370c, 0x03}, |
157 | {0x3612, 0x5b}, |
158 | {0x3618, 0x04}, |
159 | {0x5000, 0x06}, |
160 | {0x5002, 0x41}, |
161 | {0x5003, 0x08}, |
162 | {0x5a00, 0x08}, |
163 | {0x3000, 0x00}, |
164 | {0x3001, 0x00}, |
165 | {0x3002, 0x00}, |
166 | {0x3016, 0x08}, |
167 | {0x3017, 0xe0}, |
168 | {0x3018, 0x44}, |
169 | {0x301c, 0xf8}, |
170 | {0x301d, 0xf0}, |
171 | {0x3a18, 0x00}, |
172 | {0x3a19, 0xf8}, |
173 | {0x3c01, 0x80}, |
174 | {0x3b07, 0x0c}, |
175 | {0x380c, 0x0b}, |
176 | {0x380d, 0x1c}, |
177 | {0x3814, 0x11}, |
178 | {0x3815, 0x11}, |
179 | {0x3708, 0x64}, |
180 | {0x3709, 0x12}, |
181 | {0x3808, 0x0a}, |
182 | {0x3809, 0x20}, |
183 | {0x380a, 0x07}, |
184 | {0x380b, 0x98}, |
185 | {0x3800, 0x00}, |
186 | {0x3801, 0x00}, |
187 | {0x3802, 0x00}, |
188 | {0x3803, 0x00}, |
189 | {0x3804, 0x0a}, |
190 | {0x3805, 0x3f}, |
191 | {0x3806, 0x07}, |
192 | {0x3807, 0xa3}, |
193 | {0x3811, 0x10}, |
194 | {0x3813, 0x06}, |
195 | {0x3630, 0x2e}, |
196 | {0x3632, 0xe2}, |
197 | {0x3633, 0x23}, |
198 | {0x3634, 0x44}, |
199 | {0x3636, 0x06}, |
200 | {0x3620, 0x64}, |
201 | {0x3621, 0xe0}, |
202 | {0x3600, 0x37}, |
203 | {0x3704, 0xa0}, |
204 | {0x3703, 0x5a}, |
205 | {0x3715, 0x78}, |
206 | {0x3717, 0x01}, |
207 | {0x3731, 0x02}, |
208 | {0x370b, 0x60}, |
209 | {0x3705, 0x1a}, |
210 | {0x3f05, 0x02}, |
211 | {0x3f06, 0x10}, |
212 | {0x3f01, 0x0a}, |
213 | {0x3a08, 0x01}, |
214 | {0x3a09, 0x28}, |
215 | {0x3a0a, 0x00}, |
216 | {0x3a0b, 0xf6}, |
217 | {0x3a0d, 0x08}, |
218 | {0x3a0e, 0x06}, |
219 | {0x3a0f, 0x58}, |
220 | {0x3a10, 0x50}, |
221 | {0x3a1b, 0x58}, |
222 | {0x3a1e, 0x50}, |
223 | {0x3a11, 0x60}, |
224 | {0x3a1f, 0x28}, |
225 | {0x4001, 0x02}, |
226 | {0x4004, 0x04}, |
227 | {0x4000, 0x09}, |
228 | {0x4837, 0x19}, |
229 | {0x4800, 0x24}, |
230 | {0x3503, 0x03}, |
231 | {0x0100, 0x01}, |
232 | }; |
233 | |
234 | static struct regval_list ov5647_1080p30_10bpp[] = { |
235 | {0x0100, 0x00}, |
236 | {0x0103, 0x01}, |
237 | {0x3034, 0x1a}, |
238 | {0x3035, 0x21}, |
239 | {0x3036, 0x62}, |
240 | {0x303c, 0x11}, |
241 | {0x3106, 0xf5}, |
242 | {0x3821, 0x06}, |
243 | {0x3820, 0x00}, |
244 | {0x3827, 0xec}, |
245 | {0x370c, 0x03}, |
246 | {0x3612, 0x5b}, |
247 | {0x3618, 0x04}, |
248 | {0x5000, 0x06}, |
249 | {0x5002, 0x41}, |
250 | {0x5003, 0x08}, |
251 | {0x5a00, 0x08}, |
252 | {0x3000, 0x00}, |
253 | {0x3001, 0x00}, |
254 | {0x3002, 0x00}, |
255 | {0x3016, 0x08}, |
256 | {0x3017, 0xe0}, |
257 | {0x3018, 0x44}, |
258 | {0x301c, 0xf8}, |
259 | {0x301d, 0xf0}, |
260 | {0x3a18, 0x00}, |
261 | {0x3a19, 0xf8}, |
262 | {0x3c01, 0x80}, |
263 | {0x3b07, 0x0c}, |
264 | {0x380c, 0x09}, |
265 | {0x380d, 0x70}, |
266 | {0x3814, 0x11}, |
267 | {0x3815, 0x11}, |
268 | {0x3708, 0x64}, |
269 | {0x3709, 0x12}, |
270 | {0x3808, 0x07}, |
271 | {0x3809, 0x80}, |
272 | {0x380a, 0x04}, |
273 | {0x380b, 0x38}, |
274 | {0x3800, 0x01}, |
275 | {0x3801, 0x5c}, |
276 | {0x3802, 0x01}, |
277 | {0x3803, 0xb2}, |
278 | {0x3804, 0x08}, |
279 | {0x3805, 0xe3}, |
280 | {0x3806, 0x05}, |
281 | {0x3807, 0xf1}, |
282 | {0x3811, 0x04}, |
283 | {0x3813, 0x02}, |
284 | {0x3630, 0x2e}, |
285 | {0x3632, 0xe2}, |
286 | {0x3633, 0x23}, |
287 | {0x3634, 0x44}, |
288 | {0x3636, 0x06}, |
289 | {0x3620, 0x64}, |
290 | {0x3621, 0xe0}, |
291 | {0x3600, 0x37}, |
292 | {0x3704, 0xa0}, |
293 | {0x3703, 0x5a}, |
294 | {0x3715, 0x78}, |
295 | {0x3717, 0x01}, |
296 | {0x3731, 0x02}, |
297 | {0x370b, 0x60}, |
298 | {0x3705, 0x1a}, |
299 | {0x3f05, 0x02}, |
300 | {0x3f06, 0x10}, |
301 | {0x3f01, 0x0a}, |
302 | {0x3a08, 0x01}, |
303 | {0x3a09, 0x4b}, |
304 | {0x3a0a, 0x01}, |
305 | {0x3a0b, 0x13}, |
306 | {0x3a0d, 0x04}, |
307 | {0x3a0e, 0x03}, |
308 | {0x3a0f, 0x58}, |
309 | {0x3a10, 0x50}, |
310 | {0x3a1b, 0x58}, |
311 | {0x3a1e, 0x50}, |
312 | {0x3a11, 0x60}, |
313 | {0x3a1f, 0x28}, |
314 | {0x4001, 0x02}, |
315 | {0x4004, 0x04}, |
316 | {0x4000, 0x09}, |
317 | {0x4837, 0x19}, |
318 | {0x4800, 0x34}, |
319 | {0x3503, 0x03}, |
320 | {0x0100, 0x01}, |
321 | }; |
322 | |
323 | static struct regval_list ov5647_2x2binned_10bpp[] = { |
324 | {0x0100, 0x00}, |
325 | {0x0103, 0x01}, |
326 | {0x3034, 0x1a}, |
327 | {0x3035, 0x21}, |
328 | {0x3036, 0x62}, |
329 | {0x303c, 0x11}, |
330 | {0x3106, 0xf5}, |
331 | {0x3827, 0xec}, |
332 | {0x370c, 0x03}, |
333 | {0x3612, 0x59}, |
334 | {0x3618, 0x00}, |
335 | {0x5000, 0x06}, |
336 | {0x5002, 0x41}, |
337 | {0x5003, 0x08}, |
338 | {0x5a00, 0x08}, |
339 | {0x3000, 0x00}, |
340 | {0x3001, 0x00}, |
341 | {0x3002, 0x00}, |
342 | {0x3016, 0x08}, |
343 | {0x3017, 0xe0}, |
344 | {0x3018, 0x44}, |
345 | {0x301c, 0xf8}, |
346 | {0x301d, 0xf0}, |
347 | {0x3a18, 0x00}, |
348 | {0x3a19, 0xf8}, |
349 | {0x3c01, 0x80}, |
350 | {0x3b07, 0x0c}, |
351 | {0x3800, 0x00}, |
352 | {0x3801, 0x00}, |
353 | {0x3802, 0x00}, |
354 | {0x3803, 0x00}, |
355 | {0x3804, 0x0a}, |
356 | {0x3805, 0x3f}, |
357 | {0x3806, 0x07}, |
358 | {0x3807, 0xa3}, |
359 | {0x3808, 0x05}, |
360 | {0x3809, 0x10}, |
361 | {0x380a, 0x03}, |
362 | {0x380b, 0xcc}, |
363 | {0x380c, 0x07}, |
364 | {0x380d, 0x68}, |
365 | {0x3811, 0x0c}, |
366 | {0x3813, 0x06}, |
367 | {0x3814, 0x31}, |
368 | {0x3815, 0x31}, |
369 | {0x3630, 0x2e}, |
370 | {0x3632, 0xe2}, |
371 | {0x3633, 0x23}, |
372 | {0x3634, 0x44}, |
373 | {0x3636, 0x06}, |
374 | {0x3620, 0x64}, |
375 | {0x3621, 0xe0}, |
376 | {0x3600, 0x37}, |
377 | {0x3704, 0xa0}, |
378 | {0x3703, 0x5a}, |
379 | {0x3715, 0x78}, |
380 | {0x3717, 0x01}, |
381 | {0x3731, 0x02}, |
382 | {0x370b, 0x60}, |
383 | {0x3705, 0x1a}, |
384 | {0x3f05, 0x02}, |
385 | {0x3f06, 0x10}, |
386 | {0x3f01, 0x0a}, |
387 | {0x3a08, 0x01}, |
388 | {0x3a09, 0x28}, |
389 | {0x3a0a, 0x00}, |
390 | {0x3a0b, 0xf6}, |
391 | {0x3a0d, 0x08}, |
392 | {0x3a0e, 0x06}, |
393 | {0x3a0f, 0x58}, |
394 | {0x3a10, 0x50}, |
395 | {0x3a1b, 0x58}, |
396 | {0x3a1e, 0x50}, |
397 | {0x3a11, 0x60}, |
398 | {0x3a1f, 0x28}, |
399 | {0x4001, 0x02}, |
400 | {0x4004, 0x04}, |
401 | {0x4000, 0x09}, |
402 | {0x4837, 0x16}, |
403 | {0x4800, 0x24}, |
404 | {0x3503, 0x03}, |
405 | {0x3820, 0x41}, |
406 | {0x3821, 0x07}, |
407 | {0x350a, 0x00}, |
408 | {0x350b, 0x10}, |
409 | {0x3500, 0x00}, |
410 | {0x3501, 0x1a}, |
411 | {0x3502, 0xf0}, |
412 | {0x3212, 0xa0}, |
413 | {0x0100, 0x01}, |
414 | }; |
415 | |
416 | static struct regval_list ov5647_640x480_10bpp[] = { |
417 | {0x0100, 0x00}, |
418 | {0x0103, 0x01}, |
419 | {0x3035, 0x11}, |
420 | {0x3036, 0x46}, |
421 | {0x303c, 0x11}, |
422 | {0x3821, 0x07}, |
423 | {0x3820, 0x41}, |
424 | {0x370c, 0x03}, |
425 | {0x3612, 0x59}, |
426 | {0x3618, 0x00}, |
427 | {0x5000, 0x06}, |
428 | {0x5003, 0x08}, |
429 | {0x5a00, 0x08}, |
430 | {0x3000, 0xff}, |
431 | {0x3001, 0xff}, |
432 | {0x3002, 0xff}, |
433 | {0x301d, 0xf0}, |
434 | {0x3a18, 0x00}, |
435 | {0x3a19, 0xf8}, |
436 | {0x3c01, 0x80}, |
437 | {0x3b07, 0x0c}, |
438 | {0x380c, 0x07}, |
439 | {0x380d, 0x3c}, |
440 | {0x3814, 0x35}, |
441 | {0x3815, 0x35}, |
442 | {0x3708, 0x64}, |
443 | {0x3709, 0x52}, |
444 | {0x3808, 0x02}, |
445 | {0x3809, 0x80}, |
446 | {0x380a, 0x01}, |
447 | {0x380b, 0xe0}, |
448 | {0x3800, 0x00}, |
449 | {0x3801, 0x10}, |
450 | {0x3802, 0x00}, |
451 | {0x3803, 0x00}, |
452 | {0x3804, 0x0a}, |
453 | {0x3805, 0x2f}, |
454 | {0x3806, 0x07}, |
455 | {0x3807, 0x9f}, |
456 | {0x3630, 0x2e}, |
457 | {0x3632, 0xe2}, |
458 | {0x3633, 0x23}, |
459 | {0x3634, 0x44}, |
460 | {0x3620, 0x64}, |
461 | {0x3621, 0xe0}, |
462 | {0x3600, 0x37}, |
463 | {0x3704, 0xa0}, |
464 | {0x3703, 0x5a}, |
465 | {0x3715, 0x78}, |
466 | {0x3717, 0x01}, |
467 | {0x3731, 0x02}, |
468 | {0x370b, 0x60}, |
469 | {0x3705, 0x1a}, |
470 | {0x3f05, 0x02}, |
471 | {0x3f06, 0x10}, |
472 | {0x3f01, 0x0a}, |
473 | {0x3a08, 0x01}, |
474 | {0x3a09, 0x2e}, |
475 | {0x3a0a, 0x00}, |
476 | {0x3a0b, 0xfb}, |
477 | {0x3a0d, 0x02}, |
478 | {0x3a0e, 0x01}, |
479 | {0x3a0f, 0x58}, |
480 | {0x3a10, 0x50}, |
481 | {0x3a1b, 0x58}, |
482 | {0x3a1e, 0x50}, |
483 | {0x3a11, 0x60}, |
484 | {0x3a1f, 0x28}, |
485 | {0x4001, 0x02}, |
486 | {0x4004, 0x02}, |
487 | {0x4000, 0x09}, |
488 | {0x3000, 0x00}, |
489 | {0x3001, 0x00}, |
490 | {0x3002, 0x00}, |
491 | {0x3017, 0xe0}, |
492 | {0x301c, 0xfc}, |
493 | {0x3636, 0x06}, |
494 | {0x3016, 0x08}, |
495 | {0x3827, 0xec}, |
496 | {0x3018, 0x44}, |
497 | {0x3035, 0x21}, |
498 | {0x3106, 0xf5}, |
499 | {0x3034, 0x1a}, |
500 | {0x301c, 0xf8}, |
501 | {0x4800, 0x34}, |
502 | {0x3503, 0x03}, |
503 | {0x0100, 0x01}, |
504 | }; |
505 | |
506 | static const struct ov5647_mode ov5647_modes[] = { |
507 | /* 2592x1944 full resolution full FOV 10-bit mode. */ |
508 | { |
509 | .format = { |
510 | .code = MEDIA_BUS_FMT_SBGGR10_1X10, |
511 | .colorspace = V4L2_COLORSPACE_SRGB, |
512 | .field = V4L2_FIELD_NONE, |
513 | .width = 2592, |
514 | .height = 1944 |
515 | }, |
516 | .crop = { |
517 | .left = OV5647_PIXEL_ARRAY_LEFT, |
518 | .top = OV5647_PIXEL_ARRAY_TOP, |
519 | .width = 2592, |
520 | .height = 1944 |
521 | }, |
522 | .pixel_rate = 87500000, |
523 | .hts = 2844, |
524 | .vts = 0x7b0, |
525 | .reg_list = ov5647_2592x1944_10bpp, |
526 | .num_regs = ARRAY_SIZE(ov5647_2592x1944_10bpp) |
527 | }, |
528 | /* 1080p30 10-bit mode. Full resolution centre-cropped down to 1080p. */ |
529 | { |
530 | .format = { |
531 | .code = MEDIA_BUS_FMT_SBGGR10_1X10, |
532 | .colorspace = V4L2_COLORSPACE_SRGB, |
533 | .field = V4L2_FIELD_NONE, |
534 | .width = 1920, |
535 | .height = 1080 |
536 | }, |
537 | .crop = { |
538 | .left = 348 + OV5647_PIXEL_ARRAY_LEFT, |
539 | .top = 434 + OV5647_PIXEL_ARRAY_TOP, |
540 | .width = 1928, |
541 | .height = 1080, |
542 | }, |
543 | .pixel_rate = 81666700, |
544 | .hts = 2416, |
545 | .vts = 0x450, |
546 | .reg_list = ov5647_1080p30_10bpp, |
547 | .num_regs = ARRAY_SIZE(ov5647_1080p30_10bpp) |
548 | }, |
549 | /* 2x2 binned full FOV 10-bit mode. */ |
550 | { |
551 | .format = { |
552 | .code = MEDIA_BUS_FMT_SBGGR10_1X10, |
553 | .colorspace = V4L2_COLORSPACE_SRGB, |
554 | .field = V4L2_FIELD_NONE, |
555 | .width = 1296, |
556 | .height = 972 |
557 | }, |
558 | .crop = { |
559 | .left = OV5647_PIXEL_ARRAY_LEFT, |
560 | .top = OV5647_PIXEL_ARRAY_TOP, |
561 | .width = 2592, |
562 | .height = 1944, |
563 | }, |
564 | .pixel_rate = 81666700, |
565 | .hts = 1896, |
566 | .vts = 0x59b, |
567 | .reg_list = ov5647_2x2binned_10bpp, |
568 | .num_regs = ARRAY_SIZE(ov5647_2x2binned_10bpp) |
569 | }, |
570 | /* 10-bit VGA full FOV 60fps. 2x2 binned and subsampled down to VGA. */ |
571 | { |
572 | .format = { |
573 | .code = MEDIA_BUS_FMT_SBGGR10_1X10, |
574 | .colorspace = V4L2_COLORSPACE_SRGB, |
575 | .field = V4L2_FIELD_NONE, |
576 | .width = 640, |
577 | .height = 480 |
578 | }, |
579 | .crop = { |
580 | .left = 16 + OV5647_PIXEL_ARRAY_LEFT, |
581 | .top = OV5647_PIXEL_ARRAY_TOP, |
582 | .width = 2560, |
583 | .height = 1920, |
584 | }, |
585 | .pixel_rate = 55000000, |
586 | .hts = 1852, |
587 | .vts = 0x1f8, |
588 | .reg_list = ov5647_640x480_10bpp, |
589 | .num_regs = ARRAY_SIZE(ov5647_640x480_10bpp) |
590 | }, |
591 | }; |
592 | |
593 | /* Default sensor mode is 2x2 binned 640x480 SBGGR10_1X10. */ |
594 | #define OV5647_DEFAULT_MODE (&ov5647_modes[3]) |
595 | #define OV5647_DEFAULT_FORMAT (ov5647_modes[3].format) |
596 | |
597 | static int ov5647_write16(struct v4l2_subdev *sd, u16 reg, u16 val) |
598 | { |
599 | unsigned char data[4] = { reg >> 8, reg & 0xff, val >> 8, val & 0xff}; |
600 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
601 | int ret; |
602 | |
603 | ret = i2c_master_send(client, buf: data, count: 4); |
604 | if (ret < 0) { |
605 | dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n" , |
606 | __func__, reg); |
607 | return ret; |
608 | } |
609 | |
610 | return 0; |
611 | } |
612 | |
613 | static int ov5647_write(struct v4l2_subdev *sd, u16 reg, u8 val) |
614 | { |
615 | unsigned char data[3] = { reg >> 8, reg & 0xff, val}; |
616 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
617 | int ret; |
618 | |
619 | ret = i2c_master_send(client, buf: data, count: 3); |
620 | if (ret < 0) { |
621 | dev_dbg(&client->dev, "%s: i2c write error, reg: %x\n" , |
622 | __func__, reg); |
623 | return ret; |
624 | } |
625 | |
626 | return 0; |
627 | } |
628 | |
629 | static int ov5647_read(struct v4l2_subdev *sd, u16 reg, u8 *val) |
630 | { |
631 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
632 | u8 buf[2] = { reg >> 8, reg & 0xff }; |
633 | struct i2c_msg msg[2]; |
634 | int ret; |
635 | |
636 | msg[0].addr = client->addr; |
637 | msg[0].flags = client->flags; |
638 | msg[0].buf = buf; |
639 | msg[0].len = sizeof(buf); |
640 | |
641 | msg[1].addr = client->addr; |
642 | msg[1].flags = client->flags | I2C_M_RD; |
643 | msg[1].buf = buf; |
644 | msg[1].len = 1; |
645 | |
646 | ret = i2c_transfer(adap: client->adapter, msgs: msg, num: 2); |
647 | if (ret != 2) { |
648 | dev_err(&client->dev, "%s: i2c read error, reg: %x = %d\n" , |
649 | __func__, reg, ret); |
650 | return ret >= 0 ? -EINVAL : ret; |
651 | } |
652 | |
653 | *val = buf[0]; |
654 | |
655 | return 0; |
656 | } |
657 | |
658 | static int ov5647_write_array(struct v4l2_subdev *sd, |
659 | const struct regval_list *regs, int array_size) |
660 | { |
661 | int i, ret; |
662 | |
663 | for (i = 0; i < array_size; i++) { |
664 | ret = ov5647_write(sd, reg: regs[i].addr, val: regs[i].data); |
665 | if (ret < 0) |
666 | return ret; |
667 | } |
668 | |
669 | return 0; |
670 | } |
671 | |
672 | static int ov5647_set_virtual_channel(struct v4l2_subdev *sd, int channel) |
673 | { |
674 | u8 channel_id; |
675 | int ret; |
676 | |
677 | ret = ov5647_read(sd, OV5647_REG_MIPI_CTRL14, val: &channel_id); |
678 | if (ret < 0) |
679 | return ret; |
680 | |
681 | channel_id &= ~(3 << 6); |
682 | |
683 | return ov5647_write(sd, OV5647_REG_MIPI_CTRL14, |
684 | val: channel_id | (channel << 6)); |
685 | } |
686 | |
687 | static int ov5647_set_mode(struct v4l2_subdev *sd) |
688 | { |
689 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
690 | struct ov5647 *sensor = to_sensor(sd); |
691 | u8 resetval, rdval; |
692 | int ret; |
693 | |
694 | ret = ov5647_read(sd, OV5647_SW_STANDBY, val: &rdval); |
695 | if (ret < 0) |
696 | return ret; |
697 | |
698 | ret = ov5647_write_array(sd, regs: sensor->mode->reg_list, |
699 | array_size: sensor->mode->num_regs); |
700 | if (ret < 0) { |
701 | dev_err(&client->dev, "write sensor default regs error\n" ); |
702 | return ret; |
703 | } |
704 | |
705 | ret = ov5647_set_virtual_channel(sd, channel: 0); |
706 | if (ret < 0) |
707 | return ret; |
708 | |
709 | ret = ov5647_read(sd, OV5647_SW_STANDBY, val: &resetval); |
710 | if (ret < 0) |
711 | return ret; |
712 | |
713 | if (!(resetval & 0x01)) { |
714 | dev_err(&client->dev, "Device was in SW standby" ); |
715 | ret = ov5647_write(sd, OV5647_SW_STANDBY, val: 0x01); |
716 | if (ret < 0) |
717 | return ret; |
718 | } |
719 | |
720 | return 0; |
721 | } |
722 | |
723 | static int ov5647_stream_on(struct v4l2_subdev *sd) |
724 | { |
725 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
726 | struct ov5647 *sensor = to_sensor(sd); |
727 | u8 val = MIPI_CTRL00_BUS_IDLE; |
728 | int ret; |
729 | |
730 | ret = ov5647_set_mode(sd); |
731 | if (ret) { |
732 | dev_err(&client->dev, "Failed to program sensor mode: %d\n" , ret); |
733 | return ret; |
734 | } |
735 | |
736 | /* Apply customized values from user when stream starts. */ |
737 | ret = __v4l2_ctrl_handler_setup(hdl: sd->ctrl_handler); |
738 | if (ret) |
739 | return ret; |
740 | |
741 | if (sensor->clock_ncont) |
742 | val |= MIPI_CTRL00_CLOCK_LANE_GATE | |
743 | MIPI_CTRL00_LINE_SYNC_ENABLE; |
744 | |
745 | ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, val); |
746 | if (ret < 0) |
747 | return ret; |
748 | |
749 | ret = ov5647_write(sd, OV5647_REG_FRAME_OFF_NUMBER, val: 0x00); |
750 | if (ret < 0) |
751 | return ret; |
752 | |
753 | return ov5647_write(sd, OV5640_REG_PAD_OUT, val: 0x00); |
754 | } |
755 | |
756 | static int ov5647_stream_off(struct v4l2_subdev *sd) |
757 | { |
758 | int ret; |
759 | |
760 | ret = ov5647_write(sd, OV5647_REG_MIPI_CTRL00, |
761 | MIPI_CTRL00_CLOCK_LANE_GATE | MIPI_CTRL00_BUS_IDLE | |
762 | MIPI_CTRL00_CLOCK_LANE_DISABLE); |
763 | if (ret < 0) |
764 | return ret; |
765 | |
766 | ret = ov5647_write(sd, OV5647_REG_FRAME_OFF_NUMBER, val: 0x0f); |
767 | if (ret < 0) |
768 | return ret; |
769 | |
770 | return ov5647_write(sd, OV5640_REG_PAD_OUT, val: 0x01); |
771 | } |
772 | |
773 | static int ov5647_power_on(struct device *dev) |
774 | { |
775 | struct ov5647 *sensor = dev_get_drvdata(dev); |
776 | int ret; |
777 | |
778 | dev_dbg(dev, "OV5647 power on\n" ); |
779 | |
780 | if (sensor->pwdn) { |
781 | gpiod_set_value_cansleep(desc: sensor->pwdn, value: 0); |
782 | msleep(PWDN_ACTIVE_DELAY_MS); |
783 | } |
784 | |
785 | ret = clk_prepare_enable(clk: sensor->xclk); |
786 | if (ret < 0) { |
787 | dev_err(dev, "clk prepare enable failed\n" ); |
788 | goto error_pwdn; |
789 | } |
790 | |
791 | ret = ov5647_write_array(sd: &sensor->sd, regs: sensor_oe_enable_regs, |
792 | ARRAY_SIZE(sensor_oe_enable_regs)); |
793 | if (ret < 0) { |
794 | dev_err(dev, "write sensor_oe_enable_regs error\n" ); |
795 | goto error_clk_disable; |
796 | } |
797 | |
798 | /* Stream off to coax lanes into LP-11 state. */ |
799 | ret = ov5647_stream_off(sd: &sensor->sd); |
800 | if (ret < 0) { |
801 | dev_err(dev, "camera not available, check power\n" ); |
802 | goto error_clk_disable; |
803 | } |
804 | |
805 | return 0; |
806 | |
807 | error_clk_disable: |
808 | clk_disable_unprepare(clk: sensor->xclk); |
809 | error_pwdn: |
810 | gpiod_set_value_cansleep(desc: sensor->pwdn, value: 1); |
811 | |
812 | return ret; |
813 | } |
814 | |
815 | static int ov5647_power_off(struct device *dev) |
816 | { |
817 | struct ov5647 *sensor = dev_get_drvdata(dev); |
818 | u8 rdval; |
819 | int ret; |
820 | |
821 | dev_dbg(dev, "OV5647 power off\n" ); |
822 | |
823 | ret = ov5647_write_array(sd: &sensor->sd, regs: sensor_oe_disable_regs, |
824 | ARRAY_SIZE(sensor_oe_disable_regs)); |
825 | if (ret < 0) |
826 | dev_dbg(dev, "disable oe failed\n" ); |
827 | |
828 | /* Enter software standby */ |
829 | ret = ov5647_read(sd: &sensor->sd, OV5647_SW_STANDBY, val: &rdval); |
830 | if (ret < 0) |
831 | dev_dbg(dev, "software standby failed\n" ); |
832 | |
833 | rdval &= ~0x01; |
834 | ret = ov5647_write(sd: &sensor->sd, OV5647_SW_STANDBY, val: rdval); |
835 | if (ret < 0) |
836 | dev_dbg(dev, "software standby failed\n" ); |
837 | |
838 | clk_disable_unprepare(clk: sensor->xclk); |
839 | gpiod_set_value_cansleep(desc: sensor->pwdn, value: 1); |
840 | |
841 | return 0; |
842 | } |
843 | |
844 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
845 | static int ov5647_sensor_get_register(struct v4l2_subdev *sd, |
846 | struct v4l2_dbg_register *reg) |
847 | { |
848 | int ret; |
849 | u8 val; |
850 | |
851 | ret = ov5647_read(sd, reg: reg->reg & 0xff, val: &val); |
852 | if (ret < 0) |
853 | return ret; |
854 | |
855 | reg->val = val; |
856 | reg->size = 1; |
857 | |
858 | return 0; |
859 | } |
860 | |
861 | static int ov5647_sensor_set_register(struct v4l2_subdev *sd, |
862 | const struct v4l2_dbg_register *reg) |
863 | { |
864 | return ov5647_write(sd, reg: reg->reg & 0xff, val: reg->val & 0xff); |
865 | } |
866 | #endif |
867 | |
868 | /* Subdev core operations registration */ |
869 | static const struct v4l2_subdev_core_ops ov5647_subdev_core_ops = { |
870 | .subscribe_event = v4l2_ctrl_subdev_subscribe_event, |
871 | .unsubscribe_event = v4l2_event_subdev_unsubscribe, |
872 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
873 | .g_register = ov5647_sensor_get_register, |
874 | .s_register = ov5647_sensor_set_register, |
875 | #endif |
876 | }; |
877 | |
878 | static const struct v4l2_rect * |
879 | __ov5647_get_pad_crop(struct ov5647 *ov5647, |
880 | struct v4l2_subdev_state *sd_state, |
881 | unsigned int pad, enum v4l2_subdev_format_whence which) |
882 | { |
883 | switch (which) { |
884 | case V4L2_SUBDEV_FORMAT_TRY: |
885 | return v4l2_subdev_state_get_crop(sd_state, pad); |
886 | case V4L2_SUBDEV_FORMAT_ACTIVE: |
887 | return &ov5647->mode->crop; |
888 | } |
889 | |
890 | return NULL; |
891 | } |
892 | |
893 | static int ov5647_s_stream(struct v4l2_subdev *sd, int enable) |
894 | { |
895 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
896 | struct ov5647 *sensor = to_sensor(sd); |
897 | int ret; |
898 | |
899 | mutex_lock(&sensor->lock); |
900 | |
901 | if (enable) { |
902 | ret = pm_runtime_resume_and_get(dev: &client->dev); |
903 | if (ret < 0) |
904 | goto error_unlock; |
905 | |
906 | ret = ov5647_stream_on(sd); |
907 | if (ret < 0) { |
908 | dev_err(&client->dev, "stream start failed: %d\n" , ret); |
909 | goto error_pm; |
910 | } |
911 | } else { |
912 | ret = ov5647_stream_off(sd); |
913 | if (ret < 0) { |
914 | dev_err(&client->dev, "stream stop failed: %d\n" , ret); |
915 | goto error_pm; |
916 | } |
917 | pm_runtime_put(dev: &client->dev); |
918 | } |
919 | |
920 | mutex_unlock(lock: &sensor->lock); |
921 | |
922 | return 0; |
923 | |
924 | error_pm: |
925 | pm_runtime_put(dev: &client->dev); |
926 | error_unlock: |
927 | mutex_unlock(lock: &sensor->lock); |
928 | |
929 | return ret; |
930 | } |
931 | |
932 | static const struct v4l2_subdev_video_ops ov5647_subdev_video_ops = { |
933 | .s_stream = ov5647_s_stream, |
934 | }; |
935 | |
936 | static int ov5647_enum_mbus_code(struct v4l2_subdev *sd, |
937 | struct v4l2_subdev_state *sd_state, |
938 | struct v4l2_subdev_mbus_code_enum *code) |
939 | { |
940 | if (code->index > 0) |
941 | return -EINVAL; |
942 | |
943 | code->code = MEDIA_BUS_FMT_SBGGR10_1X10; |
944 | |
945 | return 0; |
946 | } |
947 | |
948 | static int ov5647_enum_frame_size(struct v4l2_subdev *sd, |
949 | struct v4l2_subdev_state *sd_state, |
950 | struct v4l2_subdev_frame_size_enum *fse) |
951 | { |
952 | const struct v4l2_mbus_framefmt *fmt; |
953 | |
954 | if (fse->code != MEDIA_BUS_FMT_SBGGR10_1X10 || |
955 | fse->index >= ARRAY_SIZE(ov5647_modes)) |
956 | return -EINVAL; |
957 | |
958 | fmt = &ov5647_modes[fse->index].format; |
959 | fse->min_width = fmt->width; |
960 | fse->max_width = fmt->width; |
961 | fse->min_height = fmt->height; |
962 | fse->max_height = fmt->height; |
963 | |
964 | return 0; |
965 | } |
966 | |
967 | static int ov5647_get_pad_fmt(struct v4l2_subdev *sd, |
968 | struct v4l2_subdev_state *sd_state, |
969 | struct v4l2_subdev_format *format) |
970 | { |
971 | struct v4l2_mbus_framefmt *fmt = &format->format; |
972 | const struct v4l2_mbus_framefmt *sensor_format; |
973 | struct ov5647 *sensor = to_sensor(sd); |
974 | |
975 | mutex_lock(&sensor->lock); |
976 | switch (format->which) { |
977 | case V4L2_SUBDEV_FORMAT_TRY: |
978 | sensor_format = v4l2_subdev_state_get_format(sd_state, |
979 | format->pad); |
980 | break; |
981 | default: |
982 | sensor_format = &sensor->mode->format; |
983 | break; |
984 | } |
985 | |
986 | *fmt = *sensor_format; |
987 | mutex_unlock(lock: &sensor->lock); |
988 | |
989 | return 0; |
990 | } |
991 | |
992 | static int ov5647_set_pad_fmt(struct v4l2_subdev *sd, |
993 | struct v4l2_subdev_state *sd_state, |
994 | struct v4l2_subdev_format *format) |
995 | { |
996 | struct v4l2_mbus_framefmt *fmt = &format->format; |
997 | struct ov5647 *sensor = to_sensor(sd); |
998 | const struct ov5647_mode *mode; |
999 | |
1000 | mode = v4l2_find_nearest_size(ov5647_modes, ARRAY_SIZE(ov5647_modes), |
1001 | format.width, format.height, |
1002 | fmt->width, fmt->height); |
1003 | |
1004 | /* Update the sensor mode and apply at it at streamon time. */ |
1005 | mutex_lock(&sensor->lock); |
1006 | if (format->which == V4L2_SUBDEV_FORMAT_TRY) { |
1007 | *v4l2_subdev_state_get_format(sd_state, format->pad) = mode->format; |
1008 | } else { |
1009 | int exposure_max, exposure_def; |
1010 | int hblank, vblank; |
1011 | |
1012 | sensor->mode = mode; |
1013 | __v4l2_ctrl_modify_range(ctrl: sensor->pixel_rate, min: mode->pixel_rate, |
1014 | max: mode->pixel_rate, step: 1, def: mode->pixel_rate); |
1015 | |
1016 | hblank = mode->hts - mode->format.width; |
1017 | __v4l2_ctrl_modify_range(ctrl: sensor->hblank, min: hblank, max: hblank, step: 1, |
1018 | def: hblank); |
1019 | |
1020 | vblank = mode->vts - mode->format.height; |
1021 | __v4l2_ctrl_modify_range(ctrl: sensor->vblank, OV5647_VBLANK_MIN, |
1022 | OV5647_VTS_MAX - mode->format.height, |
1023 | step: 1, def: vblank); |
1024 | __v4l2_ctrl_s_ctrl(ctrl: sensor->vblank, val: vblank); |
1025 | |
1026 | exposure_max = mode->vts - 4; |
1027 | exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT); |
1028 | __v4l2_ctrl_modify_range(ctrl: sensor->exposure, |
1029 | min: sensor->exposure->minimum, |
1030 | max: exposure_max, step: sensor->exposure->step, |
1031 | def: exposure_def); |
1032 | } |
1033 | *fmt = mode->format; |
1034 | mutex_unlock(lock: &sensor->lock); |
1035 | |
1036 | return 0; |
1037 | } |
1038 | |
1039 | static int ov5647_get_selection(struct v4l2_subdev *sd, |
1040 | struct v4l2_subdev_state *sd_state, |
1041 | struct v4l2_subdev_selection *sel) |
1042 | { |
1043 | switch (sel->target) { |
1044 | case V4L2_SEL_TGT_CROP: { |
1045 | struct ov5647 *sensor = to_sensor(sd); |
1046 | |
1047 | mutex_lock(&sensor->lock); |
1048 | sel->r = *__ov5647_get_pad_crop(ov5647: sensor, sd_state, pad: sel->pad, |
1049 | which: sel->which); |
1050 | mutex_unlock(lock: &sensor->lock); |
1051 | |
1052 | return 0; |
1053 | } |
1054 | |
1055 | case V4L2_SEL_TGT_NATIVE_SIZE: |
1056 | sel->r.top = 0; |
1057 | sel->r.left = 0; |
1058 | sel->r.width = OV5647_NATIVE_WIDTH; |
1059 | sel->r.height = OV5647_NATIVE_HEIGHT; |
1060 | |
1061 | return 0; |
1062 | |
1063 | case V4L2_SEL_TGT_CROP_DEFAULT: |
1064 | case V4L2_SEL_TGT_CROP_BOUNDS: |
1065 | sel->r.top = OV5647_PIXEL_ARRAY_TOP; |
1066 | sel->r.left = OV5647_PIXEL_ARRAY_LEFT; |
1067 | sel->r.width = OV5647_PIXEL_ARRAY_WIDTH; |
1068 | sel->r.height = OV5647_PIXEL_ARRAY_HEIGHT; |
1069 | |
1070 | return 0; |
1071 | } |
1072 | |
1073 | return -EINVAL; |
1074 | } |
1075 | |
1076 | static const struct v4l2_subdev_pad_ops ov5647_subdev_pad_ops = { |
1077 | .enum_mbus_code = ov5647_enum_mbus_code, |
1078 | .enum_frame_size = ov5647_enum_frame_size, |
1079 | .set_fmt = ov5647_set_pad_fmt, |
1080 | .get_fmt = ov5647_get_pad_fmt, |
1081 | .get_selection = ov5647_get_selection, |
1082 | }; |
1083 | |
1084 | static const struct v4l2_subdev_ops ov5647_subdev_ops = { |
1085 | .core = &ov5647_subdev_core_ops, |
1086 | .video = &ov5647_subdev_video_ops, |
1087 | .pad = &ov5647_subdev_pad_ops, |
1088 | }; |
1089 | |
1090 | static int ov5647_detect(struct v4l2_subdev *sd) |
1091 | { |
1092 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1093 | u8 read; |
1094 | int ret; |
1095 | |
1096 | ret = ov5647_write(sd, OV5647_SW_RESET, val: 0x01); |
1097 | if (ret < 0) |
1098 | return ret; |
1099 | |
1100 | ret = ov5647_read(sd, OV5647_REG_CHIPID_H, val: &read); |
1101 | if (ret < 0) |
1102 | return ret; |
1103 | |
1104 | if (read != 0x56) { |
1105 | dev_err(&client->dev, "ID High expected 0x56 got %x" , read); |
1106 | return -ENODEV; |
1107 | } |
1108 | |
1109 | ret = ov5647_read(sd, OV5647_REG_CHIPID_L, val: &read); |
1110 | if (ret < 0) |
1111 | return ret; |
1112 | |
1113 | if (read != 0x47) { |
1114 | dev_err(&client->dev, "ID Low expected 0x47 got %x" , read); |
1115 | return -ENODEV; |
1116 | } |
1117 | |
1118 | return ov5647_write(sd, OV5647_SW_RESET, val: 0x00); |
1119 | } |
1120 | |
1121 | static int ov5647_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) |
1122 | { |
1123 | struct v4l2_mbus_framefmt *format = |
1124 | v4l2_subdev_state_get_format(fh->state, 0); |
1125 | struct v4l2_rect *crop = v4l2_subdev_state_get_crop(fh->state, 0); |
1126 | |
1127 | crop->left = OV5647_PIXEL_ARRAY_LEFT; |
1128 | crop->top = OV5647_PIXEL_ARRAY_TOP; |
1129 | crop->width = OV5647_PIXEL_ARRAY_WIDTH; |
1130 | crop->height = OV5647_PIXEL_ARRAY_HEIGHT; |
1131 | |
1132 | *format = OV5647_DEFAULT_FORMAT; |
1133 | |
1134 | return 0; |
1135 | } |
1136 | |
1137 | static const struct v4l2_subdev_internal_ops ov5647_subdev_internal_ops = { |
1138 | .open = ov5647_open, |
1139 | }; |
1140 | |
1141 | static int ov5647_s_auto_white_balance(struct v4l2_subdev *sd, u32 val) |
1142 | { |
1143 | return ov5647_write(sd, OV5647_REG_AWB, val: val ? 1 : 0); |
1144 | } |
1145 | |
1146 | static int ov5647_s_autogain(struct v4l2_subdev *sd, u32 val) |
1147 | { |
1148 | int ret; |
1149 | u8 reg; |
1150 | |
1151 | /* Non-zero turns on AGC by clearing bit 1.*/ |
1152 | ret = ov5647_read(sd, OV5647_REG_AEC_AGC, val: ®); |
1153 | if (ret) |
1154 | return ret; |
1155 | |
1156 | return ov5647_write(sd, OV5647_REG_AEC_AGC, val: val ? reg & ~BIT(1) |
1157 | : reg | BIT(1)); |
1158 | } |
1159 | |
1160 | static int ov5647_s_exposure_auto(struct v4l2_subdev *sd, u32 val) |
1161 | { |
1162 | int ret; |
1163 | u8 reg; |
1164 | |
1165 | /* |
1166 | * Everything except V4L2_EXPOSURE_MANUAL turns on AEC by |
1167 | * clearing bit 0. |
1168 | */ |
1169 | ret = ov5647_read(sd, OV5647_REG_AEC_AGC, val: ®); |
1170 | if (ret) |
1171 | return ret; |
1172 | |
1173 | return ov5647_write(sd, OV5647_REG_AEC_AGC, |
1174 | val: val == V4L2_EXPOSURE_MANUAL ? reg | BIT(0) |
1175 | : reg & ~BIT(0)); |
1176 | } |
1177 | |
1178 | static int ov5647_s_analogue_gain(struct v4l2_subdev *sd, u32 val) |
1179 | { |
1180 | int ret; |
1181 | |
1182 | /* 10 bits of gain, 2 in the high register. */ |
1183 | ret = ov5647_write(sd, OV5647_REG_GAIN_HI, val: (val >> 8) & 3); |
1184 | if (ret) |
1185 | return ret; |
1186 | |
1187 | return ov5647_write(sd, OV5647_REG_GAIN_LO, val: val & 0xff); |
1188 | } |
1189 | |
1190 | static int ov5647_s_exposure(struct v4l2_subdev *sd, u32 val) |
1191 | { |
1192 | int ret; |
1193 | |
1194 | /* |
1195 | * Sensor has 20 bits, but the bottom 4 bits are fractions of a line |
1196 | * which we leave as zero (and don't receive in "val"). |
1197 | */ |
1198 | ret = ov5647_write(sd, OV5647_REG_EXP_HI, val: (val >> 12) & 0xf); |
1199 | if (ret) |
1200 | return ret; |
1201 | |
1202 | ret = ov5647_write(sd, OV5647_REG_EXP_MID, val: (val >> 4) & 0xff); |
1203 | if (ret) |
1204 | return ret; |
1205 | |
1206 | return ov5647_write(sd, OV5647_REG_EXP_LO, val: (val & 0xf) << 4); |
1207 | } |
1208 | |
1209 | static int ov5647_s_ctrl(struct v4l2_ctrl *ctrl) |
1210 | { |
1211 | struct ov5647 *sensor = container_of(ctrl->handler, |
1212 | struct ov5647, ctrls); |
1213 | struct v4l2_subdev *sd = &sensor->sd; |
1214 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1215 | int ret = 0; |
1216 | |
1217 | |
1218 | /* v4l2_ctrl_lock() locks our own mutex */ |
1219 | |
1220 | if (ctrl->id == V4L2_CID_VBLANK) { |
1221 | int exposure_max, exposure_def; |
1222 | |
1223 | /* Update max exposure while meeting expected vblanking */ |
1224 | exposure_max = sensor->mode->format.height + ctrl->val - 4; |
1225 | exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT); |
1226 | __v4l2_ctrl_modify_range(ctrl: sensor->exposure, |
1227 | min: sensor->exposure->minimum, |
1228 | max: exposure_max, step: sensor->exposure->step, |
1229 | def: exposure_def); |
1230 | } |
1231 | |
1232 | /* |
1233 | * If the device is not powered up do not apply any controls |
1234 | * to H/W at this time. Instead the controls will be restored |
1235 | * at s_stream(1) time. |
1236 | */ |
1237 | if (pm_runtime_get_if_in_use(dev: &client->dev) == 0) |
1238 | return 0; |
1239 | |
1240 | switch (ctrl->id) { |
1241 | case V4L2_CID_AUTO_WHITE_BALANCE: |
1242 | ret = ov5647_s_auto_white_balance(sd, val: ctrl->val); |
1243 | break; |
1244 | case V4L2_CID_AUTOGAIN: |
1245 | ret = ov5647_s_autogain(sd, val: ctrl->val); |
1246 | break; |
1247 | case V4L2_CID_EXPOSURE_AUTO: |
1248 | ret = ov5647_s_exposure_auto(sd, val: ctrl->val); |
1249 | break; |
1250 | case V4L2_CID_ANALOGUE_GAIN: |
1251 | ret = ov5647_s_analogue_gain(sd, val: ctrl->val); |
1252 | break; |
1253 | case V4L2_CID_EXPOSURE: |
1254 | ret = ov5647_s_exposure(sd, val: ctrl->val); |
1255 | break; |
1256 | case V4L2_CID_VBLANK: |
1257 | ret = ov5647_write16(sd, OV5647_REG_VTS_HI, |
1258 | val: sensor->mode->format.height + ctrl->val); |
1259 | break; |
1260 | case V4L2_CID_TEST_PATTERN: |
1261 | ret = ov5647_write(sd, OV5647_REG_ISPCTRL3D, |
1262 | val: ov5647_test_pattern_val[ctrl->val]); |
1263 | break; |
1264 | |
1265 | /* Read-only, but we adjust it based on mode. */ |
1266 | case V4L2_CID_PIXEL_RATE: |
1267 | case V4L2_CID_HBLANK: |
1268 | /* Read-only, but we adjust it based on mode. */ |
1269 | break; |
1270 | |
1271 | default: |
1272 | dev_info(&client->dev, |
1273 | "Control (id:0x%x, val:0x%x) not supported\n" , |
1274 | ctrl->id, ctrl->val); |
1275 | return -EINVAL; |
1276 | } |
1277 | |
1278 | pm_runtime_put(dev: &client->dev); |
1279 | |
1280 | return ret; |
1281 | } |
1282 | |
1283 | static const struct v4l2_ctrl_ops ov5647_ctrl_ops = { |
1284 | .s_ctrl = ov5647_s_ctrl, |
1285 | }; |
1286 | |
1287 | static int ov5647_init_controls(struct ov5647 *sensor) |
1288 | { |
1289 | struct i2c_client *client = v4l2_get_subdevdata(sd: &sensor->sd); |
1290 | int hblank, exposure_max, exposure_def; |
1291 | |
1292 | v4l2_ctrl_handler_init(&sensor->ctrls, 9); |
1293 | |
1294 | v4l2_ctrl_new_std(hdl: &sensor->ctrls, ops: &ov5647_ctrl_ops, |
1295 | V4L2_CID_AUTOGAIN, min: 0, max: 1, step: 1, def: 0); |
1296 | |
1297 | v4l2_ctrl_new_std(hdl: &sensor->ctrls, ops: &ov5647_ctrl_ops, |
1298 | V4L2_CID_AUTO_WHITE_BALANCE, min: 0, max: 1, step: 1, def: 0); |
1299 | |
1300 | v4l2_ctrl_new_std_menu(hdl: &sensor->ctrls, ops: &ov5647_ctrl_ops, |
1301 | V4L2_CID_EXPOSURE_AUTO, max: V4L2_EXPOSURE_MANUAL, |
1302 | mask: 0, def: V4L2_EXPOSURE_MANUAL); |
1303 | |
1304 | exposure_max = sensor->mode->vts - 4; |
1305 | exposure_def = min(exposure_max, OV5647_EXPOSURE_DEFAULT); |
1306 | sensor->exposure = v4l2_ctrl_new_std(hdl: &sensor->ctrls, ops: &ov5647_ctrl_ops, |
1307 | V4L2_CID_EXPOSURE, |
1308 | OV5647_EXPOSURE_MIN, |
1309 | max: exposure_max, OV5647_EXPOSURE_STEP, |
1310 | def: exposure_def); |
1311 | |
1312 | /* min: 16 = 1.0x; max (10 bits); default: 32 = 2.0x. */ |
1313 | v4l2_ctrl_new_std(hdl: &sensor->ctrls, ops: &ov5647_ctrl_ops, |
1314 | V4L2_CID_ANALOGUE_GAIN, min: 16, max: 1023, step: 1, def: 32); |
1315 | |
1316 | /* By default, PIXEL_RATE is read only, but it does change per mode */ |
1317 | sensor->pixel_rate = v4l2_ctrl_new_std(hdl: &sensor->ctrls, ops: &ov5647_ctrl_ops, |
1318 | V4L2_CID_PIXEL_RATE, |
1319 | min: sensor->mode->pixel_rate, |
1320 | max: sensor->mode->pixel_rate, step: 1, |
1321 | def: sensor->mode->pixel_rate); |
1322 | |
1323 | /* By default, HBLANK is read only, but it does change per mode. */ |
1324 | hblank = sensor->mode->hts - sensor->mode->format.width; |
1325 | sensor->hblank = v4l2_ctrl_new_std(hdl: &sensor->ctrls, ops: &ov5647_ctrl_ops, |
1326 | V4L2_CID_HBLANK, min: hblank, max: hblank, step: 1, |
1327 | def: hblank); |
1328 | |
1329 | sensor->vblank = v4l2_ctrl_new_std(hdl: &sensor->ctrls, ops: &ov5647_ctrl_ops, |
1330 | V4L2_CID_VBLANK, OV5647_VBLANK_MIN, |
1331 | OV5647_VTS_MAX - |
1332 | sensor->mode->format.height, step: 1, |
1333 | def: sensor->mode->vts - |
1334 | sensor->mode->format.height); |
1335 | |
1336 | v4l2_ctrl_new_std_menu_items(hdl: &sensor->ctrls, ops: &ov5647_ctrl_ops, |
1337 | V4L2_CID_TEST_PATTERN, |
1338 | ARRAY_SIZE(ov5647_test_pattern_menu) - 1, |
1339 | mask: 0, def: 0, qmenu: ov5647_test_pattern_menu); |
1340 | |
1341 | if (sensor->ctrls.error) |
1342 | goto handler_free; |
1343 | |
1344 | sensor->pixel_rate->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
1345 | sensor->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
1346 | sensor->sd.ctrl_handler = &sensor->ctrls; |
1347 | |
1348 | return 0; |
1349 | |
1350 | handler_free: |
1351 | dev_err(&client->dev, "%s Controls initialization failed (%d)\n" , |
1352 | __func__, sensor->ctrls.error); |
1353 | v4l2_ctrl_handler_free(hdl: &sensor->ctrls); |
1354 | |
1355 | return sensor->ctrls.error; |
1356 | } |
1357 | |
1358 | static int ov5647_parse_dt(struct ov5647 *sensor, struct device_node *np) |
1359 | { |
1360 | struct v4l2_fwnode_endpoint bus_cfg = { |
1361 | .bus_type = V4L2_MBUS_CSI2_DPHY, |
1362 | }; |
1363 | struct device_node *ep; |
1364 | int ret; |
1365 | |
1366 | ep = of_graph_get_endpoint_by_regs(parent: np, port_reg: 0, reg: -1); |
1367 | if (!ep) |
1368 | return -EINVAL; |
1369 | |
1370 | ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), vep: &bus_cfg); |
1371 | if (ret) |
1372 | goto out; |
1373 | |
1374 | sensor->clock_ncont = bus_cfg.bus.mipi_csi2.flags & |
1375 | V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK; |
1376 | |
1377 | out: |
1378 | of_node_put(node: ep); |
1379 | |
1380 | return ret; |
1381 | } |
1382 | |
1383 | static int ov5647_probe(struct i2c_client *client) |
1384 | { |
1385 | struct device_node *np = client->dev.of_node; |
1386 | struct device *dev = &client->dev; |
1387 | struct ov5647 *sensor; |
1388 | struct v4l2_subdev *sd; |
1389 | u32 xclk_freq; |
1390 | int ret; |
1391 | |
1392 | sensor = devm_kzalloc(dev, size: sizeof(*sensor), GFP_KERNEL); |
1393 | if (!sensor) |
1394 | return -ENOMEM; |
1395 | |
1396 | if (IS_ENABLED(CONFIG_OF) && np) { |
1397 | ret = ov5647_parse_dt(sensor, np); |
1398 | if (ret) { |
1399 | dev_err(dev, "DT parsing error: %d\n" , ret); |
1400 | return ret; |
1401 | } |
1402 | } |
1403 | |
1404 | sensor->xclk = devm_clk_get(dev, NULL); |
1405 | if (IS_ERR(ptr: sensor->xclk)) { |
1406 | dev_err(dev, "could not get xclk" ); |
1407 | return PTR_ERR(ptr: sensor->xclk); |
1408 | } |
1409 | |
1410 | xclk_freq = clk_get_rate(clk: sensor->xclk); |
1411 | if (xclk_freq != 25000000) { |
1412 | dev_err(dev, "Unsupported clock frequency: %u\n" , xclk_freq); |
1413 | return -EINVAL; |
1414 | } |
1415 | |
1416 | /* Request the power down GPIO asserted. */ |
1417 | sensor->pwdn = devm_gpiod_get_optional(dev, con_id: "pwdn" , flags: GPIOD_OUT_HIGH); |
1418 | if (IS_ERR(ptr: sensor->pwdn)) { |
1419 | dev_err(dev, "Failed to get 'pwdn' gpio\n" ); |
1420 | return -EINVAL; |
1421 | } |
1422 | |
1423 | mutex_init(&sensor->lock); |
1424 | |
1425 | sensor->mode = OV5647_DEFAULT_MODE; |
1426 | |
1427 | ret = ov5647_init_controls(sensor); |
1428 | if (ret) |
1429 | goto mutex_destroy; |
1430 | |
1431 | sd = &sensor->sd; |
1432 | v4l2_i2c_subdev_init(sd, client, ops: &ov5647_subdev_ops); |
1433 | sd->internal_ops = &ov5647_subdev_internal_ops; |
1434 | sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS; |
1435 | |
1436 | sensor->pad.flags = MEDIA_PAD_FL_SOURCE; |
1437 | sd->entity.function = MEDIA_ENT_F_CAM_SENSOR; |
1438 | ret = media_entity_pads_init(entity: &sd->entity, num_pads: 1, pads: &sensor->pad); |
1439 | if (ret < 0) |
1440 | goto ctrl_handler_free; |
1441 | |
1442 | ret = ov5647_power_on(dev); |
1443 | if (ret) |
1444 | goto entity_cleanup; |
1445 | |
1446 | ret = ov5647_detect(sd); |
1447 | if (ret < 0) |
1448 | goto power_off; |
1449 | |
1450 | ret = v4l2_async_register_subdev(sd); |
1451 | if (ret < 0) |
1452 | goto power_off; |
1453 | |
1454 | /* Enable runtime PM and turn off the device */ |
1455 | pm_runtime_set_active(dev); |
1456 | pm_runtime_enable(dev); |
1457 | pm_runtime_idle(dev); |
1458 | |
1459 | dev_dbg(dev, "OmniVision OV5647 camera driver probed\n" ); |
1460 | |
1461 | return 0; |
1462 | |
1463 | power_off: |
1464 | ov5647_power_off(dev); |
1465 | entity_cleanup: |
1466 | media_entity_cleanup(entity: &sd->entity); |
1467 | ctrl_handler_free: |
1468 | v4l2_ctrl_handler_free(hdl: &sensor->ctrls); |
1469 | mutex_destroy: |
1470 | mutex_destroy(lock: &sensor->lock); |
1471 | |
1472 | return ret; |
1473 | } |
1474 | |
1475 | static void ov5647_remove(struct i2c_client *client) |
1476 | { |
1477 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
1478 | struct ov5647 *sensor = to_sensor(sd); |
1479 | |
1480 | v4l2_async_unregister_subdev(sd: &sensor->sd); |
1481 | media_entity_cleanup(entity: &sensor->sd.entity); |
1482 | v4l2_ctrl_handler_free(hdl: &sensor->ctrls); |
1483 | v4l2_device_unregister_subdev(sd); |
1484 | pm_runtime_disable(dev: &client->dev); |
1485 | mutex_destroy(lock: &sensor->lock); |
1486 | } |
1487 | |
1488 | static const struct dev_pm_ops ov5647_pm_ops = { |
1489 | SET_RUNTIME_PM_OPS(ov5647_power_off, ov5647_power_on, NULL) |
1490 | }; |
1491 | |
1492 | static const struct i2c_device_id ov5647_id[] = { |
1493 | { "ov5647" , 0 }, |
1494 | { /* sentinel */ } |
1495 | }; |
1496 | MODULE_DEVICE_TABLE(i2c, ov5647_id); |
1497 | |
1498 | #if IS_ENABLED(CONFIG_OF) |
1499 | static const struct of_device_id ov5647_of_match[] = { |
1500 | { .compatible = "ovti,ov5647" }, |
1501 | { /* sentinel */ }, |
1502 | }; |
1503 | MODULE_DEVICE_TABLE(of, ov5647_of_match); |
1504 | #endif |
1505 | |
1506 | static struct i2c_driver ov5647_driver = { |
1507 | .driver = { |
1508 | .of_match_table = of_match_ptr(ov5647_of_match), |
1509 | .name = "ov5647" , |
1510 | .pm = &ov5647_pm_ops, |
1511 | }, |
1512 | .probe = ov5647_probe, |
1513 | .remove = ov5647_remove, |
1514 | .id_table = ov5647_id, |
1515 | }; |
1516 | |
1517 | module_i2c_driver(ov5647_driver); |
1518 | |
1519 | MODULE_AUTHOR("Ramiro Oliveira <roliveir@synopsys.com>" ); |
1520 | MODULE_DESCRIPTION("A low-level driver for OmniVision ov5647 sensors" ); |
1521 | MODULE_LICENSE("GPL v2" ); |
1522 | |