1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // Copyright (c) 2021 Intel Corporation. |
3 | |
4 | #include <linux/acpi.h> |
5 | #include <linux/clk.h> |
6 | #include <linux/delay.h> |
7 | #include <linux/gpio/consumer.h> |
8 | #include <linux/i2c.h> |
9 | #include <linux/module.h> |
10 | #include <linux/pm_runtime.h> |
11 | #include <media/v4l2-ctrls.h> |
12 | #include <media/v4l2-device.h> |
13 | #include <media/v4l2-fwnode.h> |
14 | |
15 | #define OV13B10_REG_VALUE_08BIT 1 |
16 | #define OV13B10_REG_VALUE_16BIT 2 |
17 | #define OV13B10_REG_VALUE_24BIT 3 |
18 | |
19 | #define OV13B10_REG_MODE_SELECT 0x0100 |
20 | #define OV13B10_MODE_STANDBY 0x00 |
21 | #define OV13B10_MODE_STREAMING 0x01 |
22 | |
23 | #define OV13B10_REG_SOFTWARE_RST 0x0103 |
24 | #define OV13B10_SOFTWARE_RST 0x01 |
25 | |
26 | /* Chip ID */ |
27 | #define OV13B10_REG_CHIP_ID 0x300a |
28 | #define OV13B10_CHIP_ID 0x560d42 |
29 | |
30 | /* V_TIMING internal */ |
31 | #define OV13B10_REG_VTS 0x380e |
32 | #define OV13B10_VTS_30FPS 0x0c7c |
33 | #define OV13B10_VTS_60FPS 0x063e |
34 | #define OV13B10_VTS_120FPS 0x0320 |
35 | #define OV13B10_VTS_MAX 0x7fff |
36 | |
37 | /* HBLANK control - read only */ |
38 | #define OV13B10_PPL_560MHZ 4704 |
39 | |
40 | /* Exposure control */ |
41 | #define OV13B10_REG_EXPOSURE 0x3500 |
42 | #define OV13B10_EXPOSURE_MIN 4 |
43 | #define OV13B10_EXPOSURE_STEP 1 |
44 | #define OV13B10_EXPOSURE_DEFAULT 0x40 |
45 | |
46 | /* Analog gain control */ |
47 | #define OV13B10_REG_ANALOG_GAIN 0x3508 |
48 | #define OV13B10_ANA_GAIN_MIN 0x80 |
49 | #define OV13B10_ANA_GAIN_MAX 0x07c0 |
50 | #define OV13B10_ANA_GAIN_STEP 1 |
51 | #define OV13B10_ANA_GAIN_DEFAULT 0x80 |
52 | |
53 | /* Digital gain control */ |
54 | #define OV13B10_REG_DGTL_GAIN_H 0x350a |
55 | #define OV13B10_REG_DGTL_GAIN_M 0x350b |
56 | #define OV13B10_REG_DGTL_GAIN_L 0x350c |
57 | |
58 | #define OV13B10_DGTL_GAIN_MIN 1024 /* Min = 1 X */ |
59 | #define OV13B10_DGTL_GAIN_MAX (4096 - 1) /* Max = 4 X */ |
60 | #define OV13B10_DGTL_GAIN_DEFAULT 2560 /* Default gain = 2.5 X */ |
61 | #define OV13B10_DGTL_GAIN_STEP 1 /* Each step = 1/1024 */ |
62 | |
63 | #define OV13B10_DGTL_GAIN_L_SHIFT 6 |
64 | #define OV13B10_DGTL_GAIN_L_MASK 0x3 |
65 | #define OV13B10_DGTL_GAIN_M_SHIFT 2 |
66 | #define OV13B10_DGTL_GAIN_M_MASK 0xff |
67 | #define OV13B10_DGTL_GAIN_H_SHIFT 10 |
68 | #define OV13B10_DGTL_GAIN_H_MASK 0x3 |
69 | |
70 | /* Test Pattern Control */ |
71 | #define OV13B10_REG_TEST_PATTERN 0x5080 |
72 | #define OV13B10_TEST_PATTERN_ENABLE BIT(7) |
73 | #define OV13B10_TEST_PATTERN_MASK 0xf3 |
74 | #define OV13B10_TEST_PATTERN_BAR_SHIFT 2 |
75 | |
76 | /* Flip Control */ |
77 | #define OV13B10_REG_FORMAT1 0x3820 |
78 | #define OV13B10_REG_FORMAT2 0x3821 |
79 | |
80 | /* Horizontal Window Offset */ |
81 | #define OV13B10_REG_H_WIN_OFFSET 0x3811 |
82 | |
83 | /* Vertical Window Offset */ |
84 | #define OV13B10_REG_V_WIN_OFFSET 0x3813 |
85 | |
86 | struct ov13b10_reg { |
87 | u16 address; |
88 | u8 val; |
89 | }; |
90 | |
91 | struct ov13b10_reg_list { |
92 | u32 num_of_regs; |
93 | const struct ov13b10_reg *regs; |
94 | }; |
95 | |
96 | /* Link frequency config */ |
97 | struct ov13b10_link_freq_config { |
98 | u32 pixels_per_line; |
99 | |
100 | /* registers for this link frequency */ |
101 | struct ov13b10_reg_list reg_list; |
102 | }; |
103 | |
104 | /* Mode : resolution and related config&values */ |
105 | struct ov13b10_mode { |
106 | /* Frame width */ |
107 | u32 width; |
108 | /* Frame height */ |
109 | u32 height; |
110 | |
111 | /* V-timing */ |
112 | u32 vts_def; |
113 | u32 vts_min; |
114 | |
115 | /* Index of Link frequency config to be used */ |
116 | u32 link_freq_index; |
117 | /* Default register values */ |
118 | struct ov13b10_reg_list reg_list; |
119 | }; |
120 | |
121 | /* 4208x3120 needs 1120Mbps/lane, 4 lanes */ |
122 | static const struct ov13b10_reg mipi_data_rate_1120mbps[] = { |
123 | {0x0103, 0x01}, |
124 | {0x0303, 0x04}, |
125 | {0x0305, 0xaf}, |
126 | {0x0321, 0x00}, |
127 | {0x0323, 0x04}, |
128 | {0x0324, 0x01}, |
129 | {0x0325, 0xa4}, |
130 | {0x0326, 0x81}, |
131 | {0x0327, 0x04}, |
132 | {0x3012, 0x07}, |
133 | {0x3013, 0x32}, |
134 | {0x3107, 0x23}, |
135 | {0x3501, 0x0c}, |
136 | {0x3502, 0x10}, |
137 | {0x3504, 0x08}, |
138 | {0x3508, 0x07}, |
139 | {0x3509, 0xc0}, |
140 | {0x3600, 0x16}, |
141 | {0x3601, 0x54}, |
142 | {0x3612, 0x4e}, |
143 | {0x3620, 0x00}, |
144 | {0x3621, 0x68}, |
145 | {0x3622, 0x66}, |
146 | {0x3623, 0x03}, |
147 | {0x3662, 0x92}, |
148 | {0x3666, 0xbb}, |
149 | {0x3667, 0x44}, |
150 | {0x366e, 0xff}, |
151 | {0x366f, 0xf3}, |
152 | {0x3675, 0x44}, |
153 | {0x3676, 0x00}, |
154 | {0x367f, 0xe9}, |
155 | {0x3681, 0x32}, |
156 | {0x3682, 0x1f}, |
157 | {0x3683, 0x0b}, |
158 | {0x3684, 0x0b}, |
159 | {0x3704, 0x0f}, |
160 | {0x3706, 0x40}, |
161 | {0x3708, 0x3b}, |
162 | {0x3709, 0x72}, |
163 | {0x370b, 0xa2}, |
164 | {0x3714, 0x24}, |
165 | {0x371a, 0x3e}, |
166 | {0x3725, 0x42}, |
167 | {0x3739, 0x12}, |
168 | {0x3767, 0x00}, |
169 | {0x377a, 0x0d}, |
170 | {0x3789, 0x18}, |
171 | {0x3790, 0x40}, |
172 | {0x3791, 0xa2}, |
173 | {0x37c2, 0x04}, |
174 | {0x37c3, 0xf1}, |
175 | {0x37d9, 0x0c}, |
176 | {0x37da, 0x02}, |
177 | {0x37dc, 0x02}, |
178 | {0x37e1, 0x04}, |
179 | {0x37e2, 0x0a}, |
180 | {0x3800, 0x00}, |
181 | {0x3801, 0x00}, |
182 | {0x3802, 0x00}, |
183 | {0x3803, 0x08}, |
184 | {0x3804, 0x10}, |
185 | {0x3805, 0x8f}, |
186 | {0x3806, 0x0c}, |
187 | {0x3807, 0x47}, |
188 | {0x3808, 0x10}, |
189 | {0x3809, 0x70}, |
190 | {0x380a, 0x0c}, |
191 | {0x380b, 0x30}, |
192 | {0x380c, 0x04}, |
193 | {0x380d, 0x98}, |
194 | {0x380e, 0x0c}, |
195 | {0x380f, 0x7c}, |
196 | {0x3811, 0x0f}, |
197 | {0x3813, 0x09}, |
198 | {0x3814, 0x01}, |
199 | {0x3815, 0x01}, |
200 | {0x3816, 0x01}, |
201 | {0x3817, 0x01}, |
202 | {0x381f, 0x08}, |
203 | {0x3820, 0x88}, |
204 | {0x3821, 0x00}, |
205 | {0x3822, 0x14}, |
206 | {0x382e, 0xe6}, |
207 | {0x3c80, 0x00}, |
208 | {0x3c87, 0x01}, |
209 | {0x3c8c, 0x19}, |
210 | {0x3c8d, 0x1c}, |
211 | {0x3ca0, 0x00}, |
212 | {0x3ca1, 0x00}, |
213 | {0x3ca2, 0x00}, |
214 | {0x3ca3, 0x00}, |
215 | {0x3ca4, 0x50}, |
216 | {0x3ca5, 0x11}, |
217 | {0x3ca6, 0x01}, |
218 | {0x3ca7, 0x00}, |
219 | {0x3ca8, 0x00}, |
220 | {0x4008, 0x02}, |
221 | {0x4009, 0x0f}, |
222 | {0x400a, 0x01}, |
223 | {0x400b, 0x19}, |
224 | {0x4011, 0x21}, |
225 | {0x4017, 0x08}, |
226 | {0x4019, 0x04}, |
227 | {0x401a, 0x58}, |
228 | {0x4032, 0x1e}, |
229 | {0x4050, 0x02}, |
230 | {0x4051, 0x09}, |
231 | {0x405e, 0x00}, |
232 | {0x4066, 0x02}, |
233 | {0x4501, 0x00}, |
234 | {0x4502, 0x10}, |
235 | {0x4505, 0x00}, |
236 | {0x4800, 0x64}, |
237 | {0x481b, 0x3e}, |
238 | {0x481f, 0x30}, |
239 | {0x4825, 0x34}, |
240 | {0x4837, 0x0e}, |
241 | {0x484b, 0x01}, |
242 | {0x4883, 0x02}, |
243 | {0x5000, 0xff}, |
244 | {0x5001, 0x0f}, |
245 | {0x5045, 0x20}, |
246 | {0x5046, 0x20}, |
247 | {0x5047, 0xa4}, |
248 | {0x5048, 0x20}, |
249 | {0x5049, 0xa4}, |
250 | }; |
251 | |
252 | static const struct ov13b10_reg mode_4208x3120_regs[] = { |
253 | {0x0305, 0xaf}, |
254 | {0x3501, 0x0c}, |
255 | {0x3662, 0x92}, |
256 | {0x3714, 0x24}, |
257 | {0x3739, 0x12}, |
258 | {0x37c2, 0x04}, |
259 | {0x37d9, 0x0c}, |
260 | {0x37e2, 0x0a}, |
261 | {0x3800, 0x00}, |
262 | {0x3801, 0x00}, |
263 | {0x3802, 0x00}, |
264 | {0x3803, 0x08}, |
265 | {0x3804, 0x10}, |
266 | {0x3805, 0x8f}, |
267 | {0x3806, 0x0c}, |
268 | {0x3807, 0x47}, |
269 | {0x3808, 0x10}, |
270 | {0x3809, 0x70}, |
271 | {0x380a, 0x0c}, |
272 | {0x380b, 0x30}, |
273 | {0x380c, 0x04}, |
274 | {0x380d, 0x98}, |
275 | {0x380e, 0x0c}, |
276 | {0x380f, 0x7c}, |
277 | {0x3810, 0x00}, |
278 | {0x3811, 0x0f}, |
279 | {0x3812, 0x00}, |
280 | {0x3813, 0x09}, |
281 | {0x3814, 0x01}, |
282 | {0x3816, 0x01}, |
283 | {0x3820, 0x88}, |
284 | {0x3c8c, 0x19}, |
285 | {0x4008, 0x02}, |
286 | {0x4009, 0x0f}, |
287 | {0x4050, 0x02}, |
288 | {0x4051, 0x09}, |
289 | {0x4501, 0x00}, |
290 | {0x4505, 0x00}, |
291 | {0x4837, 0x0e}, |
292 | {0x5000, 0xff}, |
293 | {0x5001, 0x0f}, |
294 | }; |
295 | |
296 | static const struct ov13b10_reg mode_4160x3120_regs[] = { |
297 | {0x0305, 0xaf}, |
298 | {0x3501, 0x0c}, |
299 | {0x3662, 0x92}, |
300 | {0x3714, 0x24}, |
301 | {0x3739, 0x12}, |
302 | {0x37c2, 0x04}, |
303 | {0x37d9, 0x0c}, |
304 | {0x37e2, 0x0a}, |
305 | {0x3800, 0x00}, |
306 | {0x3801, 0x00}, |
307 | {0x3802, 0x00}, |
308 | {0x3803, 0x08}, |
309 | {0x3804, 0x10}, |
310 | {0x3805, 0x8f}, |
311 | {0x3806, 0x0c}, |
312 | {0x3807, 0x47}, |
313 | {0x3808, 0x10}, |
314 | {0x3809, 0x40}, |
315 | {0x380a, 0x0c}, |
316 | {0x380b, 0x30}, |
317 | {0x380c, 0x04}, |
318 | {0x380d, 0x98}, |
319 | {0x380e, 0x0c}, |
320 | {0x380f, 0x7c}, |
321 | {0x3810, 0x00}, |
322 | {0x3811, 0x27}, |
323 | {0x3812, 0x00}, |
324 | {0x3813, 0x09}, |
325 | {0x3814, 0x01}, |
326 | {0x3816, 0x01}, |
327 | {0x3820, 0x88}, |
328 | {0x3c8c, 0x19}, |
329 | {0x4008, 0x02}, |
330 | {0x4009, 0x0f}, |
331 | {0x4050, 0x02}, |
332 | {0x4051, 0x09}, |
333 | {0x4501, 0x00}, |
334 | {0x4505, 0x00}, |
335 | {0x4837, 0x0e}, |
336 | {0x5000, 0xff}, |
337 | {0x5001, 0x0f}, |
338 | }; |
339 | |
340 | static const struct ov13b10_reg mode_4160x2340_regs[] = { |
341 | {0x0305, 0xaf}, |
342 | {0x3501, 0x0c}, |
343 | {0x3662, 0x92}, |
344 | {0x3714, 0x24}, |
345 | {0x3739, 0x12}, |
346 | {0x37c2, 0x04}, |
347 | {0x37d9, 0x0c}, |
348 | {0x37e2, 0x0a}, |
349 | {0x3800, 0x00}, |
350 | {0x3801, 0x00}, |
351 | {0x3802, 0x00}, |
352 | {0x3803, 0x08}, |
353 | {0x3804, 0x10}, |
354 | {0x3805, 0x8f}, |
355 | {0x3806, 0x0c}, |
356 | {0x3807, 0x47}, |
357 | {0x3808, 0x10}, |
358 | {0x3809, 0x40}, |
359 | {0x380a, 0x09}, |
360 | {0x380b, 0x24}, |
361 | {0x380c, 0x04}, |
362 | {0x380d, 0x98}, |
363 | {0x380e, 0x0c}, |
364 | {0x380f, 0x7c}, |
365 | {0x3810, 0x00}, |
366 | {0x3811, 0x27}, |
367 | {0x3812, 0x01}, |
368 | {0x3813, 0x8f}, |
369 | {0x3814, 0x01}, |
370 | {0x3816, 0x01}, |
371 | {0x3820, 0x88}, |
372 | {0x3c8c, 0x19}, |
373 | {0x4008, 0x02}, |
374 | {0x4009, 0x0f}, |
375 | {0x4050, 0x02}, |
376 | {0x4051, 0x09}, |
377 | {0x4501, 0x00}, |
378 | {0x4505, 0x00}, |
379 | {0x4837, 0x0e}, |
380 | {0x5000, 0xff}, |
381 | {0x5001, 0x0f}, |
382 | }; |
383 | |
384 | static const struct ov13b10_reg mode_2104x1560_regs[] = { |
385 | {0x0305, 0xaf}, |
386 | {0x3501, 0x06}, |
387 | {0x3662, 0x88}, |
388 | {0x3714, 0x28}, |
389 | {0x3739, 0x10}, |
390 | {0x37c2, 0x14}, |
391 | {0x37d9, 0x06}, |
392 | {0x37e2, 0x0c}, |
393 | {0x3800, 0x00}, |
394 | {0x3801, 0x00}, |
395 | {0x3802, 0x00}, |
396 | {0x3803, 0x08}, |
397 | {0x3804, 0x10}, |
398 | {0x3805, 0x8f}, |
399 | {0x3806, 0x0c}, |
400 | {0x3807, 0x47}, |
401 | {0x3808, 0x08}, |
402 | {0x3809, 0x38}, |
403 | {0x380a, 0x06}, |
404 | {0x380b, 0x18}, |
405 | {0x380c, 0x04}, |
406 | {0x380d, 0x98}, |
407 | {0x380e, 0x06}, |
408 | {0x380f, 0x3e}, |
409 | {0x3810, 0x00}, |
410 | {0x3811, 0x07}, |
411 | {0x3812, 0x00}, |
412 | {0x3813, 0x05}, |
413 | {0x3814, 0x03}, |
414 | {0x3816, 0x03}, |
415 | {0x3820, 0x8b}, |
416 | {0x3c8c, 0x18}, |
417 | {0x4008, 0x00}, |
418 | {0x4009, 0x05}, |
419 | {0x4050, 0x00}, |
420 | {0x4051, 0x05}, |
421 | {0x4501, 0x08}, |
422 | {0x4505, 0x00}, |
423 | {0x4837, 0x0e}, |
424 | {0x5000, 0xfd}, |
425 | {0x5001, 0x0d}, |
426 | }; |
427 | |
428 | static const struct ov13b10_reg mode_2080x1170_regs[] = { |
429 | {0x0305, 0xaf}, |
430 | {0x3501, 0x06}, |
431 | {0x3662, 0x88}, |
432 | {0x3714, 0x28}, |
433 | {0x3739, 0x10}, |
434 | {0x37c2, 0x14}, |
435 | {0x37d9, 0x06}, |
436 | {0x37e2, 0x0c}, |
437 | {0x3800, 0x00}, |
438 | {0x3801, 0x00}, |
439 | {0x3802, 0x00}, |
440 | {0x3803, 0x08}, |
441 | {0x3804, 0x10}, |
442 | {0x3805, 0x8f}, |
443 | {0x3806, 0x0c}, |
444 | {0x3807, 0x47}, |
445 | {0x3808, 0x08}, |
446 | {0x3809, 0x20}, |
447 | {0x380a, 0x04}, |
448 | {0x380b, 0x92}, |
449 | {0x380c, 0x04}, |
450 | {0x380d, 0x98}, |
451 | {0x380e, 0x06}, |
452 | {0x380f, 0x3e}, |
453 | {0x3810, 0x00}, |
454 | {0x3811, 0x13}, |
455 | {0x3812, 0x00}, |
456 | {0x3813, 0xc9}, |
457 | {0x3814, 0x03}, |
458 | {0x3816, 0x03}, |
459 | {0x3820, 0x8b}, |
460 | {0x3c8c, 0x18}, |
461 | {0x4008, 0x00}, |
462 | {0x4009, 0x05}, |
463 | {0x4050, 0x00}, |
464 | {0x4051, 0x05}, |
465 | {0x4501, 0x08}, |
466 | {0x4505, 0x00}, |
467 | {0x4837, 0x0e}, |
468 | {0x5000, 0xfd}, |
469 | {0x5001, 0x0d}, |
470 | }; |
471 | |
472 | static const struct ov13b10_reg mode_1364x768_120fps_regs[] = { |
473 | {0x0305, 0xaf}, |
474 | {0x3011, 0x7c}, |
475 | {0x3501, 0x03}, |
476 | {0x3502, 0x00}, |
477 | {0x3662, 0x88}, |
478 | {0x3714, 0x28}, |
479 | {0x3739, 0x10}, |
480 | {0x37c2, 0x14}, |
481 | {0x37d9, 0x06}, |
482 | {0x37e2, 0x0c}, |
483 | {0x37e4, 0x00}, |
484 | {0x3800, 0x02}, |
485 | {0x3801, 0xe4}, |
486 | {0x3802, 0x03}, |
487 | {0x3803, 0x48}, |
488 | {0x3804, 0x0d}, |
489 | {0x3805, 0xab}, |
490 | {0x3806, 0x09}, |
491 | {0x3807, 0x60}, |
492 | {0x3808, 0x05}, |
493 | {0x3809, 0x54}, |
494 | {0x380a, 0x03}, |
495 | {0x380b, 0x00}, |
496 | {0x380c, 0x04}, |
497 | {0x380d, 0x8e}, |
498 | {0x380e, 0x03}, |
499 | {0x380f, 0x20}, |
500 | {0x3811, 0x07}, |
501 | {0x3813, 0x07}, |
502 | {0x3814, 0x03}, |
503 | {0x3816, 0x03}, |
504 | {0x3820, 0x8b}, |
505 | {0x3c8c, 0x18}, |
506 | {0x4008, 0x00}, |
507 | {0x4009, 0x05}, |
508 | {0x4050, 0x00}, |
509 | {0x4051, 0x05}, |
510 | {0x4501, 0x08}, |
511 | {0x4505, 0x04}, |
512 | {0x5000, 0xfd}, |
513 | {0x5001, 0x0d}, |
514 | }; |
515 | |
516 | static const char * const [] = { |
517 | "Disabled" , |
518 | "Vertical Color Bar Type 1" , |
519 | "Vertical Color Bar Type 2" , |
520 | "Vertical Color Bar Type 3" , |
521 | "Vertical Color Bar Type 4" |
522 | }; |
523 | |
524 | /* Configurations for supported link frequencies */ |
525 | #define OV13B10_LINK_FREQ_560MHZ 560000000ULL |
526 | #define OV13B10_LINK_FREQ_INDEX_0 0 |
527 | |
528 | #define OV13B10_EXT_CLK 19200000 |
529 | #define OV13B10_DATA_LANES 4 |
530 | |
531 | /* |
532 | * pixel_rate = link_freq * data-rate * nr_of_lanes / bits_per_sample |
533 | * data rate => double data rate; number of lanes => 4; bits per pixel => 10 |
534 | */ |
535 | static u64 link_freq_to_pixel_rate(u64 f) |
536 | { |
537 | f *= 2 * OV13B10_DATA_LANES; |
538 | do_div(f, 10); |
539 | |
540 | return f; |
541 | } |
542 | |
543 | /* Menu items for LINK_FREQ V4L2 control */ |
544 | static const s64 [] = { |
545 | OV13B10_LINK_FREQ_560MHZ |
546 | }; |
547 | |
548 | /* Link frequency configs */ |
549 | static const struct ov13b10_link_freq_config |
550 | link_freq_configs[] = { |
551 | { |
552 | .pixels_per_line = OV13B10_PPL_560MHZ, |
553 | .reg_list = { |
554 | .num_of_regs = ARRAY_SIZE(mipi_data_rate_1120mbps), |
555 | .regs = mipi_data_rate_1120mbps, |
556 | } |
557 | } |
558 | }; |
559 | |
560 | /* Mode configs */ |
561 | static const struct ov13b10_mode supported_modes[] = { |
562 | { |
563 | .width = 4208, |
564 | .height = 3120, |
565 | .vts_def = OV13B10_VTS_30FPS, |
566 | .vts_min = OV13B10_VTS_30FPS, |
567 | .reg_list = { |
568 | .num_of_regs = ARRAY_SIZE(mode_4208x3120_regs), |
569 | .regs = mode_4208x3120_regs, |
570 | }, |
571 | .link_freq_index = OV13B10_LINK_FREQ_INDEX_0, |
572 | }, |
573 | { |
574 | .width = 4160, |
575 | .height = 3120, |
576 | .vts_def = OV13B10_VTS_30FPS, |
577 | .vts_min = OV13B10_VTS_30FPS, |
578 | .reg_list = { |
579 | .num_of_regs = ARRAY_SIZE(mode_4160x3120_regs), |
580 | .regs = mode_4160x3120_regs, |
581 | }, |
582 | .link_freq_index = OV13B10_LINK_FREQ_INDEX_0, |
583 | }, |
584 | { |
585 | .width = 4160, |
586 | .height = 2340, |
587 | .vts_def = OV13B10_VTS_30FPS, |
588 | .vts_min = OV13B10_VTS_30FPS, |
589 | .reg_list = { |
590 | .num_of_regs = ARRAY_SIZE(mode_4160x2340_regs), |
591 | .regs = mode_4160x2340_regs, |
592 | }, |
593 | .link_freq_index = OV13B10_LINK_FREQ_INDEX_0, |
594 | }, |
595 | { |
596 | .width = 2104, |
597 | .height = 1560, |
598 | .vts_def = OV13B10_VTS_60FPS, |
599 | .vts_min = OV13B10_VTS_60FPS, |
600 | .reg_list = { |
601 | .num_of_regs = ARRAY_SIZE(mode_2104x1560_regs), |
602 | .regs = mode_2104x1560_regs, |
603 | }, |
604 | .link_freq_index = OV13B10_LINK_FREQ_INDEX_0, |
605 | }, |
606 | { |
607 | .width = 2080, |
608 | .height = 1170, |
609 | .vts_def = OV13B10_VTS_60FPS, |
610 | .vts_min = OV13B10_VTS_60FPS, |
611 | .reg_list = { |
612 | .num_of_regs = ARRAY_SIZE(mode_2080x1170_regs), |
613 | .regs = mode_2080x1170_regs, |
614 | }, |
615 | .link_freq_index = OV13B10_LINK_FREQ_INDEX_0, |
616 | }, |
617 | { |
618 | .width = 1364, |
619 | .height = 768, |
620 | .vts_def = OV13B10_VTS_120FPS, |
621 | .vts_min = OV13B10_VTS_120FPS, |
622 | .link_freq_index = OV13B10_LINK_FREQ_INDEX_0, |
623 | .reg_list = { |
624 | .num_of_regs = ARRAY_SIZE(mode_1364x768_120fps_regs), |
625 | .regs = mode_1364x768_120fps_regs, |
626 | }, |
627 | }, |
628 | }; |
629 | |
630 | struct ov13b10 { |
631 | struct v4l2_subdev sd; |
632 | struct media_pad pad; |
633 | |
634 | struct v4l2_ctrl_handler ctrl_handler; |
635 | |
636 | struct clk *img_clk; |
637 | struct regulator *avdd; |
638 | struct gpio_desc *reset; |
639 | |
640 | /* V4L2 Controls */ |
641 | struct v4l2_ctrl *link_freq; |
642 | struct v4l2_ctrl *pixel_rate; |
643 | struct v4l2_ctrl *vblank; |
644 | struct v4l2_ctrl *hblank; |
645 | struct v4l2_ctrl *exposure; |
646 | |
647 | /* Current mode */ |
648 | const struct ov13b10_mode *cur_mode; |
649 | |
650 | /* Mutex for serialized access */ |
651 | struct mutex mutex; |
652 | |
653 | /* True if the device has been identified */ |
654 | bool identified; |
655 | }; |
656 | |
657 | #define to_ov13b10(_sd) container_of(_sd, struct ov13b10, sd) |
658 | |
659 | /* Read registers up to 4 at a time */ |
660 | static int ov13b10_read_reg(struct ov13b10 *ov13b, |
661 | u16 reg, u32 len, u32 *val) |
662 | { |
663 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov13b->sd); |
664 | struct i2c_msg msgs[2]; |
665 | u8 *data_be_p; |
666 | int ret; |
667 | __be32 data_be = 0; |
668 | __be16 reg_addr_be = cpu_to_be16(reg); |
669 | |
670 | if (len > 4) |
671 | return -EINVAL; |
672 | |
673 | data_be_p = (u8 *)&data_be; |
674 | /* Write register address */ |
675 | msgs[0].addr = client->addr; |
676 | msgs[0].flags = 0; |
677 | msgs[0].len = 2; |
678 | msgs[0].buf = (u8 *)®_addr_be; |
679 | |
680 | /* Read data from register */ |
681 | msgs[1].addr = client->addr; |
682 | msgs[1].flags = I2C_M_RD; |
683 | msgs[1].len = len; |
684 | msgs[1].buf = &data_be_p[4 - len]; |
685 | |
686 | ret = i2c_transfer(adap: client->adapter, msgs, ARRAY_SIZE(msgs)); |
687 | if (ret != ARRAY_SIZE(msgs)) |
688 | return -EIO; |
689 | |
690 | *val = be32_to_cpu(data_be); |
691 | |
692 | return 0; |
693 | } |
694 | |
695 | /* Write registers up to 4 at a time */ |
696 | static int ov13b10_write_reg(struct ov13b10 *ov13b, |
697 | u16 reg, u32 len, u32 __val) |
698 | { |
699 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov13b->sd); |
700 | int buf_i, val_i; |
701 | u8 buf[6], *val_p; |
702 | __be32 val; |
703 | |
704 | if (len > 4) |
705 | return -EINVAL; |
706 | |
707 | buf[0] = reg >> 8; |
708 | buf[1] = reg & 0xff; |
709 | |
710 | val = cpu_to_be32(__val); |
711 | val_p = (u8 *)&val; |
712 | buf_i = 2; |
713 | val_i = 4 - len; |
714 | |
715 | while (val_i < 4) |
716 | buf[buf_i++] = val_p[val_i++]; |
717 | |
718 | if (i2c_master_send(client, buf, count: len + 2) != len + 2) |
719 | return -EIO; |
720 | |
721 | return 0; |
722 | } |
723 | |
724 | /* Write a list of registers */ |
725 | static int ov13b10_write_regs(struct ov13b10 *ov13b, |
726 | const struct ov13b10_reg *regs, u32 len) |
727 | { |
728 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov13b->sd); |
729 | int ret; |
730 | u32 i; |
731 | |
732 | for (i = 0; i < len; i++) { |
733 | ret = ov13b10_write_reg(ov13b, reg: regs[i].address, len: 1, |
734 | val: regs[i].val); |
735 | if (ret) { |
736 | dev_err_ratelimited(&client->dev, |
737 | "Failed to write reg 0x%4.4x. error = %d\n" , |
738 | regs[i].address, ret); |
739 | |
740 | return ret; |
741 | } |
742 | } |
743 | |
744 | return 0; |
745 | } |
746 | |
747 | static int ov13b10_write_reg_list(struct ov13b10 *ov13b, |
748 | const struct ov13b10_reg_list *r_list) |
749 | { |
750 | return ov13b10_write_regs(ov13b, regs: r_list->regs, len: r_list->num_of_regs); |
751 | } |
752 | |
753 | /* Open sub-device */ |
754 | static int ov13b10_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh) |
755 | { |
756 | const struct ov13b10_mode *default_mode = &supported_modes[0]; |
757 | struct ov13b10 *ov13b = to_ov13b10(sd); |
758 | struct v4l2_mbus_framefmt *try_fmt = v4l2_subdev_state_get_format(fh->state, |
759 | 0); |
760 | |
761 | mutex_lock(&ov13b->mutex); |
762 | |
763 | /* Initialize try_fmt */ |
764 | try_fmt->width = default_mode->width; |
765 | try_fmt->height = default_mode->height; |
766 | try_fmt->code = MEDIA_BUS_FMT_SGRBG10_1X10; |
767 | try_fmt->field = V4L2_FIELD_NONE; |
768 | |
769 | /* No crop or compose */ |
770 | mutex_unlock(lock: &ov13b->mutex); |
771 | |
772 | return 0; |
773 | } |
774 | |
775 | static int ov13b10_update_digital_gain(struct ov13b10 *ov13b, u32 d_gain) |
776 | { |
777 | int ret; |
778 | u32 val; |
779 | |
780 | /* |
781 | * 0x350C[7:6], 0x350B[7:0], 0x350A[1:0] |
782 | */ |
783 | |
784 | val = (d_gain & OV13B10_DGTL_GAIN_L_MASK) << OV13B10_DGTL_GAIN_L_SHIFT; |
785 | ret = ov13b10_write_reg(ov13b, OV13B10_REG_DGTL_GAIN_L, |
786 | OV13B10_REG_VALUE_08BIT, val: val); |
787 | if (ret) |
788 | return ret; |
789 | |
790 | val = (d_gain >> OV13B10_DGTL_GAIN_M_SHIFT) & OV13B10_DGTL_GAIN_M_MASK; |
791 | ret = ov13b10_write_reg(ov13b, OV13B10_REG_DGTL_GAIN_M, |
792 | OV13B10_REG_VALUE_08BIT, val: val); |
793 | if (ret) |
794 | return ret; |
795 | |
796 | val = (d_gain >> OV13B10_DGTL_GAIN_H_SHIFT) & OV13B10_DGTL_GAIN_H_MASK; |
797 | ret = ov13b10_write_reg(ov13b, OV13B10_REG_DGTL_GAIN_H, |
798 | OV13B10_REG_VALUE_08BIT, val: val); |
799 | |
800 | return ret; |
801 | } |
802 | |
803 | static int ov13b10_enable_test_pattern(struct ov13b10 *ov13b, u32 pattern) |
804 | { |
805 | int ret; |
806 | u32 val; |
807 | |
808 | ret = ov13b10_read_reg(ov13b, OV13B10_REG_TEST_PATTERN, |
809 | OV13B10_REG_VALUE_08BIT, val: &val); |
810 | if (ret) |
811 | return ret; |
812 | |
813 | if (pattern) { |
814 | val &= OV13B10_TEST_PATTERN_MASK; |
815 | val |= ((pattern - 1) << OV13B10_TEST_PATTERN_BAR_SHIFT) | |
816 | OV13B10_TEST_PATTERN_ENABLE; |
817 | } else { |
818 | val &= ~OV13B10_TEST_PATTERN_ENABLE; |
819 | } |
820 | |
821 | return ov13b10_write_reg(ov13b, OV13B10_REG_TEST_PATTERN, |
822 | OV13B10_REG_VALUE_08BIT, val: val); |
823 | } |
824 | |
825 | static int ov13b10_set_ctrl_hflip(struct ov13b10 *ov13b, u32 ctrl_val) |
826 | { |
827 | int ret; |
828 | u32 val; |
829 | |
830 | ret = ov13b10_read_reg(ov13b, OV13B10_REG_FORMAT1, |
831 | OV13B10_REG_VALUE_08BIT, val: &val); |
832 | if (ret) |
833 | return ret; |
834 | |
835 | ret = ov13b10_write_reg(ov13b, OV13B10_REG_FORMAT1, |
836 | OV13B10_REG_VALUE_08BIT, |
837 | val: ctrl_val ? val & ~BIT(3) : val); |
838 | |
839 | if (ret) |
840 | return ret; |
841 | |
842 | ret = ov13b10_read_reg(ov13b, OV13B10_REG_H_WIN_OFFSET, |
843 | OV13B10_REG_VALUE_08BIT, val: &val); |
844 | if (ret) |
845 | return ret; |
846 | |
847 | /* |
848 | * Applying cropping offset to reverse the change of Bayer order |
849 | * after mirroring image |
850 | */ |
851 | return ov13b10_write_reg(ov13b, OV13B10_REG_H_WIN_OFFSET, |
852 | OV13B10_REG_VALUE_08BIT, |
853 | val: ctrl_val ? ++val : val); |
854 | } |
855 | |
856 | static int ov13b10_set_ctrl_vflip(struct ov13b10 *ov13b, u32 ctrl_val) |
857 | { |
858 | int ret; |
859 | u32 val; |
860 | |
861 | ret = ov13b10_read_reg(ov13b, OV13B10_REG_FORMAT1, |
862 | OV13B10_REG_VALUE_08BIT, val: &val); |
863 | if (ret) |
864 | return ret; |
865 | |
866 | ret = ov13b10_write_reg(ov13b, OV13B10_REG_FORMAT1, |
867 | OV13B10_REG_VALUE_08BIT, |
868 | val: ctrl_val ? val | BIT(4) | BIT(5) : val); |
869 | |
870 | if (ret) |
871 | return ret; |
872 | |
873 | ret = ov13b10_read_reg(ov13b, OV13B10_REG_V_WIN_OFFSET, |
874 | OV13B10_REG_VALUE_08BIT, val: &val); |
875 | if (ret) |
876 | return ret; |
877 | |
878 | /* |
879 | * Applying cropping offset to reverse the change of Bayer order |
880 | * after flipping image |
881 | */ |
882 | return ov13b10_write_reg(ov13b, OV13B10_REG_V_WIN_OFFSET, |
883 | OV13B10_REG_VALUE_08BIT, |
884 | val: ctrl_val ? --val : val); |
885 | } |
886 | |
887 | static int ov13b10_set_ctrl(struct v4l2_ctrl *ctrl) |
888 | { |
889 | struct ov13b10 *ov13b = container_of(ctrl->handler, |
890 | struct ov13b10, ctrl_handler); |
891 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov13b->sd); |
892 | s64 max; |
893 | int ret; |
894 | |
895 | /* Propagate change of current control to all related controls */ |
896 | switch (ctrl->id) { |
897 | case V4L2_CID_VBLANK: |
898 | /* Update max exposure while meeting expected vblanking */ |
899 | max = ov13b->cur_mode->height + ctrl->val - 8; |
900 | __v4l2_ctrl_modify_range(ctrl: ov13b->exposure, |
901 | min: ov13b->exposure->minimum, |
902 | max, step: ov13b->exposure->step, def: max); |
903 | break; |
904 | } |
905 | |
906 | /* |
907 | * Applying V4L2 control value only happens |
908 | * when power is up for streaming |
909 | */ |
910 | if (!pm_runtime_get_if_in_use(dev: &client->dev)) |
911 | return 0; |
912 | |
913 | ret = 0; |
914 | switch (ctrl->id) { |
915 | case V4L2_CID_ANALOGUE_GAIN: |
916 | ret = ov13b10_write_reg(ov13b, OV13B10_REG_ANALOG_GAIN, |
917 | OV13B10_REG_VALUE_16BIT, |
918 | val: ctrl->val << 1); |
919 | break; |
920 | case V4L2_CID_DIGITAL_GAIN: |
921 | ret = ov13b10_update_digital_gain(ov13b, d_gain: ctrl->val); |
922 | break; |
923 | case V4L2_CID_EXPOSURE: |
924 | ret = ov13b10_write_reg(ov13b, OV13B10_REG_EXPOSURE, |
925 | OV13B10_REG_VALUE_24BIT, |
926 | val: ctrl->val); |
927 | break; |
928 | case V4L2_CID_VBLANK: |
929 | ret = ov13b10_write_reg(ov13b, OV13B10_REG_VTS, |
930 | OV13B10_REG_VALUE_16BIT, |
931 | val: ov13b->cur_mode->height |
932 | + ctrl->val); |
933 | break; |
934 | case V4L2_CID_TEST_PATTERN: |
935 | ret = ov13b10_enable_test_pattern(ov13b, pattern: ctrl->val); |
936 | break; |
937 | case V4L2_CID_HFLIP: |
938 | ov13b10_set_ctrl_hflip(ov13b, ctrl_val: ctrl->val); |
939 | break; |
940 | case V4L2_CID_VFLIP: |
941 | ov13b10_set_ctrl_vflip(ov13b, ctrl_val: ctrl->val); |
942 | break; |
943 | default: |
944 | dev_info(&client->dev, |
945 | "ctrl(id:0x%x,val:0x%x) is not handled\n" , |
946 | ctrl->id, ctrl->val); |
947 | break; |
948 | } |
949 | |
950 | pm_runtime_put(dev: &client->dev); |
951 | |
952 | return ret; |
953 | } |
954 | |
955 | static const struct v4l2_ctrl_ops ov13b10_ctrl_ops = { |
956 | .s_ctrl = ov13b10_set_ctrl, |
957 | }; |
958 | |
959 | static int ov13b10_enum_mbus_code(struct v4l2_subdev *sd, |
960 | struct v4l2_subdev_state *sd_state, |
961 | struct v4l2_subdev_mbus_code_enum *code) |
962 | { |
963 | /* Only one bayer order(GRBG) is supported */ |
964 | if (code->index > 0) |
965 | return -EINVAL; |
966 | |
967 | code->code = MEDIA_BUS_FMT_SGRBG10_1X10; |
968 | |
969 | return 0; |
970 | } |
971 | |
972 | static int ov13b10_enum_frame_size(struct v4l2_subdev *sd, |
973 | struct v4l2_subdev_state *sd_state, |
974 | struct v4l2_subdev_frame_size_enum *fse) |
975 | { |
976 | if (fse->index >= ARRAY_SIZE(supported_modes)) |
977 | return -EINVAL; |
978 | |
979 | if (fse->code != MEDIA_BUS_FMT_SGRBG10_1X10) |
980 | return -EINVAL; |
981 | |
982 | fse->min_width = supported_modes[fse->index].width; |
983 | fse->max_width = fse->min_width; |
984 | fse->min_height = supported_modes[fse->index].height; |
985 | fse->max_height = fse->min_height; |
986 | |
987 | return 0; |
988 | } |
989 | |
990 | static void ov13b10_update_pad_format(const struct ov13b10_mode *mode, |
991 | struct v4l2_subdev_format *fmt) |
992 | { |
993 | fmt->format.width = mode->width; |
994 | fmt->format.height = mode->height; |
995 | fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; |
996 | fmt->format.field = V4L2_FIELD_NONE; |
997 | } |
998 | |
999 | static int ov13b10_do_get_pad_format(struct ov13b10 *ov13b, |
1000 | struct v4l2_subdev_state *sd_state, |
1001 | struct v4l2_subdev_format *fmt) |
1002 | { |
1003 | struct v4l2_mbus_framefmt *framefmt; |
1004 | |
1005 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1006 | framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); |
1007 | fmt->format = *framefmt; |
1008 | } else { |
1009 | ov13b10_update_pad_format(mode: ov13b->cur_mode, fmt); |
1010 | } |
1011 | |
1012 | return 0; |
1013 | } |
1014 | |
1015 | static int ov13b10_get_pad_format(struct v4l2_subdev *sd, |
1016 | struct v4l2_subdev_state *sd_state, |
1017 | struct v4l2_subdev_format *fmt) |
1018 | { |
1019 | struct ov13b10 *ov13b = to_ov13b10(sd); |
1020 | int ret; |
1021 | |
1022 | mutex_lock(&ov13b->mutex); |
1023 | ret = ov13b10_do_get_pad_format(ov13b, sd_state, fmt); |
1024 | mutex_unlock(lock: &ov13b->mutex); |
1025 | |
1026 | return ret; |
1027 | } |
1028 | |
1029 | static int |
1030 | ov13b10_set_pad_format(struct v4l2_subdev *sd, |
1031 | struct v4l2_subdev_state *sd_state, |
1032 | struct v4l2_subdev_format *fmt) |
1033 | { |
1034 | struct ov13b10 *ov13b = to_ov13b10(sd); |
1035 | const struct ov13b10_mode *mode; |
1036 | struct v4l2_mbus_framefmt *framefmt; |
1037 | s32 vblank_def; |
1038 | s32 vblank_min; |
1039 | s64 h_blank; |
1040 | s64 pixel_rate; |
1041 | s64 link_freq; |
1042 | |
1043 | mutex_lock(&ov13b->mutex); |
1044 | |
1045 | /* Only one raw bayer(GRBG) order is supported */ |
1046 | if (fmt->format.code != MEDIA_BUS_FMT_SGRBG10_1X10) |
1047 | fmt->format.code = MEDIA_BUS_FMT_SGRBG10_1X10; |
1048 | |
1049 | mode = v4l2_find_nearest_size(supported_modes, |
1050 | ARRAY_SIZE(supported_modes), |
1051 | width, height, |
1052 | fmt->format.width, fmt->format.height); |
1053 | ov13b10_update_pad_format(mode, fmt); |
1054 | if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) { |
1055 | framefmt = v4l2_subdev_state_get_format(sd_state, fmt->pad); |
1056 | *framefmt = fmt->format; |
1057 | } else { |
1058 | ov13b->cur_mode = mode; |
1059 | __v4l2_ctrl_s_ctrl(ctrl: ov13b->link_freq, val: mode->link_freq_index); |
1060 | link_freq = link_freq_menu_items[mode->link_freq_index]; |
1061 | pixel_rate = link_freq_to_pixel_rate(f: link_freq); |
1062 | __v4l2_ctrl_s_ctrl_int64(ctrl: ov13b->pixel_rate, val: pixel_rate); |
1063 | |
1064 | /* Update limits and set FPS to default */ |
1065 | vblank_def = ov13b->cur_mode->vts_def - |
1066 | ov13b->cur_mode->height; |
1067 | vblank_min = ov13b->cur_mode->vts_min - |
1068 | ov13b->cur_mode->height; |
1069 | __v4l2_ctrl_modify_range(ctrl: ov13b->vblank, min: vblank_min, |
1070 | OV13B10_VTS_MAX |
1071 | - ov13b->cur_mode->height, |
1072 | step: 1, |
1073 | def: vblank_def); |
1074 | __v4l2_ctrl_s_ctrl(ctrl: ov13b->vblank, val: vblank_def); |
1075 | h_blank = |
1076 | link_freq_configs[mode->link_freq_index].pixels_per_line |
1077 | - ov13b->cur_mode->width; |
1078 | __v4l2_ctrl_modify_range(ctrl: ov13b->hblank, min: h_blank, |
1079 | max: h_blank, step: 1, def: h_blank); |
1080 | } |
1081 | |
1082 | mutex_unlock(lock: &ov13b->mutex); |
1083 | |
1084 | return 0; |
1085 | } |
1086 | |
1087 | /* Verify chip ID */ |
1088 | static int ov13b10_identify_module(struct ov13b10 *ov13b) |
1089 | { |
1090 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov13b->sd); |
1091 | int ret; |
1092 | u32 val; |
1093 | |
1094 | if (ov13b->identified) |
1095 | return 0; |
1096 | |
1097 | ret = ov13b10_read_reg(ov13b, OV13B10_REG_CHIP_ID, |
1098 | OV13B10_REG_VALUE_24BIT, val: &val); |
1099 | if (ret) |
1100 | return ret; |
1101 | |
1102 | if (val != OV13B10_CHIP_ID) { |
1103 | dev_err(&client->dev, "chip id mismatch: %x!=%x\n" , |
1104 | OV13B10_CHIP_ID, val); |
1105 | return -EIO; |
1106 | } |
1107 | |
1108 | ov13b->identified = true; |
1109 | |
1110 | return 0; |
1111 | } |
1112 | |
1113 | static int ov13b10_power_off(struct device *dev) |
1114 | { |
1115 | struct v4l2_subdev *sd = dev_get_drvdata(dev); |
1116 | struct ov13b10 *ov13b10 = to_ov13b10(sd); |
1117 | |
1118 | gpiod_set_value_cansleep(desc: ov13b10->reset, value: 1); |
1119 | |
1120 | if (ov13b10->avdd) |
1121 | regulator_disable(regulator: ov13b10->avdd); |
1122 | |
1123 | clk_disable_unprepare(clk: ov13b10->img_clk); |
1124 | |
1125 | return 0; |
1126 | } |
1127 | |
1128 | static int ov13b10_power_on(struct device *dev) |
1129 | { |
1130 | struct v4l2_subdev *sd = dev_get_drvdata(dev); |
1131 | struct ov13b10 *ov13b10 = to_ov13b10(sd); |
1132 | int ret; |
1133 | |
1134 | ret = clk_prepare_enable(clk: ov13b10->img_clk); |
1135 | if (ret < 0) { |
1136 | dev_err(dev, "failed to enable imaging clock: %d" , ret); |
1137 | return ret; |
1138 | } |
1139 | |
1140 | if (ov13b10->avdd) { |
1141 | ret = regulator_enable(regulator: ov13b10->avdd); |
1142 | if (ret < 0) { |
1143 | dev_err(dev, "failed to enable avdd: %d" , ret); |
1144 | clk_disable_unprepare(clk: ov13b10->img_clk); |
1145 | return ret; |
1146 | } |
1147 | } |
1148 | |
1149 | gpiod_set_value_cansleep(desc: ov13b10->reset, value: 0); |
1150 | /* 5ms to wait ready after XSHUTDN assert */ |
1151 | usleep_range(min: 5000, max: 5500); |
1152 | |
1153 | return 0; |
1154 | } |
1155 | |
1156 | static int ov13b10_start_streaming(struct ov13b10 *ov13b) |
1157 | { |
1158 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov13b->sd); |
1159 | const struct ov13b10_reg_list *reg_list; |
1160 | int ret, link_freq_index; |
1161 | |
1162 | ret = ov13b10_identify_module(ov13b); |
1163 | if (ret) |
1164 | return ret; |
1165 | |
1166 | /* Get out of from software reset */ |
1167 | ret = ov13b10_write_reg(ov13b, OV13B10_REG_SOFTWARE_RST, |
1168 | OV13B10_REG_VALUE_08BIT, OV13B10_SOFTWARE_RST); |
1169 | if (ret) { |
1170 | dev_err(&client->dev, "%s failed to set powerup registers\n" , |
1171 | __func__); |
1172 | return ret; |
1173 | } |
1174 | |
1175 | link_freq_index = ov13b->cur_mode->link_freq_index; |
1176 | reg_list = &link_freq_configs[link_freq_index].reg_list; |
1177 | ret = ov13b10_write_reg_list(ov13b, r_list: reg_list); |
1178 | if (ret) { |
1179 | dev_err(&client->dev, "%s failed to set plls\n" , __func__); |
1180 | return ret; |
1181 | } |
1182 | |
1183 | /* Apply default values of current mode */ |
1184 | reg_list = &ov13b->cur_mode->reg_list; |
1185 | ret = ov13b10_write_reg_list(ov13b, r_list: reg_list); |
1186 | if (ret) { |
1187 | dev_err(&client->dev, "%s failed to set mode\n" , __func__); |
1188 | return ret; |
1189 | } |
1190 | |
1191 | /* Apply customized values from user */ |
1192 | ret = __v4l2_ctrl_handler_setup(hdl: ov13b->sd.ctrl_handler); |
1193 | if (ret) |
1194 | return ret; |
1195 | |
1196 | return ov13b10_write_reg(ov13b, OV13B10_REG_MODE_SELECT, |
1197 | OV13B10_REG_VALUE_08BIT, |
1198 | OV13B10_MODE_STREAMING); |
1199 | } |
1200 | |
1201 | /* Stop streaming */ |
1202 | static int ov13b10_stop_streaming(struct ov13b10 *ov13b) |
1203 | { |
1204 | return ov13b10_write_reg(ov13b, OV13B10_REG_MODE_SELECT, |
1205 | OV13B10_REG_VALUE_08BIT, OV13B10_MODE_STANDBY); |
1206 | } |
1207 | |
1208 | static int ov13b10_set_stream(struct v4l2_subdev *sd, int enable) |
1209 | { |
1210 | struct ov13b10 *ov13b = to_ov13b10(sd); |
1211 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
1212 | int ret = 0; |
1213 | |
1214 | mutex_lock(&ov13b->mutex); |
1215 | |
1216 | if (enable) { |
1217 | ret = pm_runtime_resume_and_get(dev: &client->dev); |
1218 | if (ret < 0) |
1219 | goto err_unlock; |
1220 | |
1221 | /* |
1222 | * Apply default & customized values |
1223 | * and then start streaming. |
1224 | */ |
1225 | ret = ov13b10_start_streaming(ov13b); |
1226 | if (ret) |
1227 | goto err_rpm_put; |
1228 | } else { |
1229 | ov13b10_stop_streaming(ov13b); |
1230 | pm_runtime_put(dev: &client->dev); |
1231 | } |
1232 | |
1233 | mutex_unlock(lock: &ov13b->mutex); |
1234 | |
1235 | return ret; |
1236 | |
1237 | err_rpm_put: |
1238 | pm_runtime_put(dev: &client->dev); |
1239 | err_unlock: |
1240 | mutex_unlock(lock: &ov13b->mutex); |
1241 | |
1242 | return ret; |
1243 | } |
1244 | |
1245 | static int ov13b10_suspend(struct device *dev) |
1246 | { |
1247 | ov13b10_power_off(dev); |
1248 | |
1249 | return 0; |
1250 | } |
1251 | |
1252 | static int ov13b10_resume(struct device *dev) |
1253 | { |
1254 | return ov13b10_power_on(dev); |
1255 | } |
1256 | |
1257 | static const struct v4l2_subdev_video_ops ov13b10_video_ops = { |
1258 | .s_stream = ov13b10_set_stream, |
1259 | }; |
1260 | |
1261 | static const struct v4l2_subdev_pad_ops ov13b10_pad_ops = { |
1262 | .enum_mbus_code = ov13b10_enum_mbus_code, |
1263 | .get_fmt = ov13b10_get_pad_format, |
1264 | .set_fmt = ov13b10_set_pad_format, |
1265 | .enum_frame_size = ov13b10_enum_frame_size, |
1266 | }; |
1267 | |
1268 | static const struct v4l2_subdev_ops ov13b10_subdev_ops = { |
1269 | .video = &ov13b10_video_ops, |
1270 | .pad = &ov13b10_pad_ops, |
1271 | }; |
1272 | |
1273 | static const struct media_entity_operations ov13b10_subdev_entity_ops = { |
1274 | .link_validate = v4l2_subdev_link_validate, |
1275 | }; |
1276 | |
1277 | static const struct v4l2_subdev_internal_ops ov13b10_internal_ops = { |
1278 | .open = ov13b10_open, |
1279 | }; |
1280 | |
1281 | /* Initialize control handlers */ |
1282 | static int ov13b10_init_controls(struct ov13b10 *ov13b) |
1283 | { |
1284 | struct i2c_client *client = v4l2_get_subdevdata(sd: &ov13b->sd); |
1285 | struct v4l2_fwnode_device_properties props; |
1286 | struct v4l2_ctrl_handler *ctrl_hdlr; |
1287 | s64 exposure_max; |
1288 | s64 vblank_def; |
1289 | s64 vblank_min; |
1290 | s64 hblank; |
1291 | s64 pixel_rate_min; |
1292 | s64 pixel_rate_max; |
1293 | const struct ov13b10_mode *mode; |
1294 | u32 max; |
1295 | int ret; |
1296 | |
1297 | ctrl_hdlr = &ov13b->ctrl_handler; |
1298 | ret = v4l2_ctrl_handler_init(ctrl_hdlr, 10); |
1299 | if (ret) |
1300 | return ret; |
1301 | |
1302 | mutex_init(&ov13b->mutex); |
1303 | ctrl_hdlr->lock = &ov13b->mutex; |
1304 | max = ARRAY_SIZE(link_freq_menu_items) - 1; |
1305 | ov13b->link_freq = v4l2_ctrl_new_int_menu(hdl: ctrl_hdlr, |
1306 | ops: &ov13b10_ctrl_ops, |
1307 | V4L2_CID_LINK_FREQ, |
1308 | max, |
1309 | def: 0, |
1310 | qmenu_int: link_freq_menu_items); |
1311 | if (ov13b->link_freq) |
1312 | ov13b->link_freq->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
1313 | |
1314 | pixel_rate_max = link_freq_to_pixel_rate(f: link_freq_menu_items[0]); |
1315 | pixel_rate_min = 0; |
1316 | /* By default, PIXEL_RATE is read only */ |
1317 | ov13b->pixel_rate = v4l2_ctrl_new_std(hdl: ctrl_hdlr, ops: &ov13b10_ctrl_ops, |
1318 | V4L2_CID_PIXEL_RATE, |
1319 | min: pixel_rate_min, max: pixel_rate_max, |
1320 | step: 1, def: pixel_rate_max); |
1321 | |
1322 | mode = ov13b->cur_mode; |
1323 | vblank_def = mode->vts_def - mode->height; |
1324 | vblank_min = mode->vts_min - mode->height; |
1325 | ov13b->vblank = v4l2_ctrl_new_std(hdl: ctrl_hdlr, ops: &ov13b10_ctrl_ops, |
1326 | V4L2_CID_VBLANK, |
1327 | min: vblank_min, |
1328 | OV13B10_VTS_MAX - mode->height, step: 1, |
1329 | def: vblank_def); |
1330 | |
1331 | hblank = link_freq_configs[mode->link_freq_index].pixels_per_line - |
1332 | mode->width; |
1333 | ov13b->hblank = v4l2_ctrl_new_std(hdl: ctrl_hdlr, ops: &ov13b10_ctrl_ops, |
1334 | V4L2_CID_HBLANK, |
1335 | min: hblank, max: hblank, step: 1, def: hblank); |
1336 | if (ov13b->hblank) |
1337 | ov13b->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
1338 | |
1339 | exposure_max = mode->vts_def - 8; |
1340 | ov13b->exposure = v4l2_ctrl_new_std(hdl: ctrl_hdlr, ops: &ov13b10_ctrl_ops, |
1341 | V4L2_CID_EXPOSURE, |
1342 | OV13B10_EXPOSURE_MIN, |
1343 | max: exposure_max, OV13B10_EXPOSURE_STEP, |
1344 | def: exposure_max); |
1345 | |
1346 | v4l2_ctrl_new_std(hdl: ctrl_hdlr, ops: &ov13b10_ctrl_ops, V4L2_CID_ANALOGUE_GAIN, |
1347 | OV13B10_ANA_GAIN_MIN, OV13B10_ANA_GAIN_MAX, |
1348 | OV13B10_ANA_GAIN_STEP, OV13B10_ANA_GAIN_DEFAULT); |
1349 | |
1350 | /* Digital gain */ |
1351 | v4l2_ctrl_new_std(hdl: ctrl_hdlr, ops: &ov13b10_ctrl_ops, V4L2_CID_DIGITAL_GAIN, |
1352 | OV13B10_DGTL_GAIN_MIN, OV13B10_DGTL_GAIN_MAX, |
1353 | OV13B10_DGTL_GAIN_STEP, OV13B10_DGTL_GAIN_DEFAULT); |
1354 | |
1355 | v4l2_ctrl_new_std_menu_items(hdl: ctrl_hdlr, ops: &ov13b10_ctrl_ops, |
1356 | V4L2_CID_TEST_PATTERN, |
1357 | ARRAY_SIZE(ov13b10_test_pattern_menu) - 1, |
1358 | mask: 0, def: 0, qmenu: ov13b10_test_pattern_menu); |
1359 | |
1360 | v4l2_ctrl_new_std(hdl: ctrl_hdlr, ops: &ov13b10_ctrl_ops, |
1361 | V4L2_CID_HFLIP, min: 0, max: 1, step: 1, def: 0); |
1362 | v4l2_ctrl_new_std(hdl: ctrl_hdlr, ops: &ov13b10_ctrl_ops, |
1363 | V4L2_CID_VFLIP, min: 0, max: 1, step: 1, def: 0); |
1364 | |
1365 | if (ctrl_hdlr->error) { |
1366 | ret = ctrl_hdlr->error; |
1367 | dev_err(&client->dev, "%s control init failed (%d)\n" , |
1368 | __func__, ret); |
1369 | goto error; |
1370 | } |
1371 | |
1372 | ret = v4l2_fwnode_device_parse(dev: &client->dev, props: &props); |
1373 | if (ret) |
1374 | goto error; |
1375 | |
1376 | ret = v4l2_ctrl_new_fwnode_properties(hdl: ctrl_hdlr, ctrl_ops: &ov13b10_ctrl_ops, |
1377 | p: &props); |
1378 | if (ret) |
1379 | goto error; |
1380 | |
1381 | ov13b->sd.ctrl_handler = ctrl_hdlr; |
1382 | |
1383 | return 0; |
1384 | |
1385 | error: |
1386 | v4l2_ctrl_handler_free(hdl: ctrl_hdlr); |
1387 | mutex_destroy(lock: &ov13b->mutex); |
1388 | |
1389 | return ret; |
1390 | } |
1391 | |
1392 | static void ov13b10_free_controls(struct ov13b10 *ov13b) |
1393 | { |
1394 | v4l2_ctrl_handler_free(hdl: ov13b->sd.ctrl_handler); |
1395 | mutex_destroy(lock: &ov13b->mutex); |
1396 | } |
1397 | |
1398 | static int ov13b10_get_pm_resources(struct device *dev) |
1399 | { |
1400 | struct v4l2_subdev *sd = dev_get_drvdata(dev); |
1401 | struct ov13b10 *ov13b = to_ov13b10(sd); |
1402 | int ret; |
1403 | |
1404 | ov13b->reset = devm_gpiod_get_optional(dev, con_id: "reset" , flags: GPIOD_OUT_LOW); |
1405 | if (IS_ERR(ptr: ov13b->reset)) |
1406 | return dev_err_probe(dev, err: PTR_ERR(ptr: ov13b->reset), |
1407 | fmt: "failed to get reset gpio\n" ); |
1408 | |
1409 | ov13b->img_clk = devm_clk_get_optional(dev, NULL); |
1410 | if (IS_ERR(ptr: ov13b->img_clk)) |
1411 | return dev_err_probe(dev, err: PTR_ERR(ptr: ov13b->img_clk), |
1412 | fmt: "failed to get imaging clock\n" ); |
1413 | |
1414 | ov13b->avdd = devm_regulator_get_optional(dev, id: "avdd" ); |
1415 | if (IS_ERR(ptr: ov13b->avdd)) { |
1416 | ret = PTR_ERR(ptr: ov13b->avdd); |
1417 | ov13b->avdd = NULL; |
1418 | if (ret != -ENODEV) |
1419 | return dev_err_probe(dev, err: ret, |
1420 | fmt: "failed to get avdd regulator\n" ); |
1421 | } |
1422 | |
1423 | return 0; |
1424 | } |
1425 | |
1426 | static int ov13b10_check_hwcfg(struct device *dev) |
1427 | { |
1428 | struct v4l2_fwnode_endpoint bus_cfg = { |
1429 | .bus_type = V4L2_MBUS_CSI2_DPHY |
1430 | }; |
1431 | struct fwnode_handle *ep; |
1432 | struct fwnode_handle *fwnode = dev_fwnode(dev); |
1433 | unsigned int i, j; |
1434 | int ret; |
1435 | u32 ext_clk; |
1436 | |
1437 | if (!fwnode) |
1438 | return -ENXIO; |
1439 | |
1440 | ep = fwnode_graph_get_next_endpoint(fwnode, NULL); |
1441 | if (!ep) |
1442 | return -EPROBE_DEFER; |
1443 | |
1444 | ret = fwnode_property_read_u32(dev_fwnode(dev), propname: "clock-frequency" , |
1445 | val: &ext_clk); |
1446 | if (ret) { |
1447 | dev_err(dev, "can't get clock frequency" ); |
1448 | return ret; |
1449 | } |
1450 | |
1451 | if (ext_clk != OV13B10_EXT_CLK) { |
1452 | dev_err(dev, "external clock %d is not supported" , |
1453 | ext_clk); |
1454 | return -EINVAL; |
1455 | } |
1456 | |
1457 | ret = v4l2_fwnode_endpoint_alloc_parse(fwnode: ep, vep: &bus_cfg); |
1458 | fwnode_handle_put(fwnode: ep); |
1459 | if (ret) |
1460 | return ret; |
1461 | |
1462 | if (bus_cfg.bus.mipi_csi2.num_data_lanes != OV13B10_DATA_LANES) { |
1463 | dev_err(dev, "number of CSI2 data lanes %d is not supported" , |
1464 | bus_cfg.bus.mipi_csi2.num_data_lanes); |
1465 | ret = -EINVAL; |
1466 | goto out_err; |
1467 | } |
1468 | |
1469 | if (!bus_cfg.nr_of_link_frequencies) { |
1470 | dev_err(dev, "no link frequencies defined" ); |
1471 | ret = -EINVAL; |
1472 | goto out_err; |
1473 | } |
1474 | |
1475 | for (i = 0; i < ARRAY_SIZE(link_freq_menu_items); i++) { |
1476 | for (j = 0; j < bus_cfg.nr_of_link_frequencies; j++) { |
1477 | if (link_freq_menu_items[i] == |
1478 | bus_cfg.link_frequencies[j]) |
1479 | break; |
1480 | } |
1481 | |
1482 | if (j == bus_cfg.nr_of_link_frequencies) { |
1483 | dev_err(dev, "no link frequency %lld supported" , |
1484 | link_freq_menu_items[i]); |
1485 | ret = -EINVAL; |
1486 | goto out_err; |
1487 | } |
1488 | } |
1489 | |
1490 | out_err: |
1491 | v4l2_fwnode_endpoint_free(vep: &bus_cfg); |
1492 | |
1493 | return ret; |
1494 | } |
1495 | |
1496 | static int ov13b10_probe(struct i2c_client *client) |
1497 | { |
1498 | struct ov13b10 *ov13b; |
1499 | bool full_power; |
1500 | int ret; |
1501 | |
1502 | /* Check HW config */ |
1503 | ret = ov13b10_check_hwcfg(dev: &client->dev); |
1504 | if (ret) { |
1505 | dev_err(&client->dev, "failed to check hwcfg: %d" , ret); |
1506 | return ret; |
1507 | } |
1508 | |
1509 | ov13b = devm_kzalloc(dev: &client->dev, size: sizeof(*ov13b), GFP_KERNEL); |
1510 | if (!ov13b) |
1511 | return -ENOMEM; |
1512 | |
1513 | /* Initialize subdev */ |
1514 | v4l2_i2c_subdev_init(sd: &ov13b->sd, client, ops: &ov13b10_subdev_ops); |
1515 | |
1516 | ret = ov13b10_get_pm_resources(dev: &client->dev); |
1517 | if (ret) |
1518 | return ret; |
1519 | |
1520 | full_power = acpi_dev_state_d0(dev: &client->dev); |
1521 | if (full_power) { |
1522 | ret = ov13b10_power_on(dev: &client->dev); |
1523 | if (ret) { |
1524 | dev_err(&client->dev, "failed to power on\n" ); |
1525 | return ret; |
1526 | } |
1527 | |
1528 | /* Check module identity */ |
1529 | ret = ov13b10_identify_module(ov13b); |
1530 | if (ret) { |
1531 | dev_err(&client->dev, "failed to find sensor: %d\n" , ret); |
1532 | goto error_power_off; |
1533 | } |
1534 | } |
1535 | |
1536 | /* Set default mode to max resolution */ |
1537 | ov13b->cur_mode = &supported_modes[0]; |
1538 | |
1539 | ret = ov13b10_init_controls(ov13b); |
1540 | if (ret) |
1541 | goto error_power_off; |
1542 | |
1543 | /* Initialize subdev */ |
1544 | ov13b->sd.internal_ops = &ov13b10_internal_ops; |
1545 | ov13b->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; |
1546 | ov13b->sd.entity.ops = &ov13b10_subdev_entity_ops; |
1547 | ov13b->sd.entity.function = MEDIA_ENT_F_CAM_SENSOR; |
1548 | |
1549 | /* Initialize source pad */ |
1550 | ov13b->pad.flags = MEDIA_PAD_FL_SOURCE; |
1551 | ret = media_entity_pads_init(entity: &ov13b->sd.entity, num_pads: 1, pads: &ov13b->pad); |
1552 | if (ret) { |
1553 | dev_err(&client->dev, "%s failed:%d\n" , __func__, ret); |
1554 | goto error_handler_free; |
1555 | } |
1556 | |
1557 | |
1558 | /* |
1559 | * Device is already turned on by i2c-core with ACPI domain PM. |
1560 | * Enable runtime PM and turn off the device. |
1561 | */ |
1562 | /* Set the device's state to active if it's in D0 state. */ |
1563 | if (full_power) |
1564 | pm_runtime_set_active(dev: &client->dev); |
1565 | pm_runtime_enable(dev: &client->dev); |
1566 | pm_runtime_idle(dev: &client->dev); |
1567 | |
1568 | ret = v4l2_async_register_subdev_sensor(sd: &ov13b->sd); |
1569 | if (ret < 0) |
1570 | goto error_media_entity_runtime_pm; |
1571 | |
1572 | return 0; |
1573 | |
1574 | error_media_entity_runtime_pm: |
1575 | pm_runtime_disable(dev: &client->dev); |
1576 | if (full_power) |
1577 | pm_runtime_set_suspended(dev: &client->dev); |
1578 | media_entity_cleanup(entity: &ov13b->sd.entity); |
1579 | |
1580 | error_handler_free: |
1581 | ov13b10_free_controls(ov13b); |
1582 | dev_err(&client->dev, "%s failed:%d\n" , __func__, ret); |
1583 | |
1584 | error_power_off: |
1585 | ov13b10_power_off(dev: &client->dev); |
1586 | |
1587 | return ret; |
1588 | } |
1589 | |
1590 | static void ov13b10_remove(struct i2c_client *client) |
1591 | { |
1592 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
1593 | struct ov13b10 *ov13b = to_ov13b10(sd); |
1594 | |
1595 | v4l2_async_unregister_subdev(sd); |
1596 | media_entity_cleanup(entity: &sd->entity); |
1597 | ov13b10_free_controls(ov13b); |
1598 | |
1599 | pm_runtime_disable(dev: &client->dev); |
1600 | pm_runtime_set_suspended(dev: &client->dev); |
1601 | } |
1602 | |
1603 | static DEFINE_RUNTIME_DEV_PM_OPS(ov13b10_pm_ops, ov13b10_suspend, |
1604 | ov13b10_resume, NULL); |
1605 | |
1606 | #ifdef CONFIG_ACPI |
1607 | static const struct acpi_device_id ov13b10_acpi_ids[] = { |
1608 | {"OVTIDB10" }, |
1609 | {"OVTI13B1" }, |
1610 | { /* sentinel */ } |
1611 | }; |
1612 | |
1613 | MODULE_DEVICE_TABLE(acpi, ov13b10_acpi_ids); |
1614 | #endif |
1615 | |
1616 | static struct i2c_driver ov13b10_i2c_driver = { |
1617 | .driver = { |
1618 | .name = "ov13b10" , |
1619 | .pm = pm_ptr(&ov13b10_pm_ops), |
1620 | .acpi_match_table = ACPI_PTR(ov13b10_acpi_ids), |
1621 | }, |
1622 | .probe = ov13b10_probe, |
1623 | .remove = ov13b10_remove, |
1624 | .flags = I2C_DRV_ACPI_WAIVE_D0_PROBE, |
1625 | }; |
1626 | |
1627 | module_i2c_driver(ov13b10_i2c_driver); |
1628 | |
1629 | MODULE_AUTHOR("Kao, Arec <arec.kao@intel.com>" ); |
1630 | MODULE_DESCRIPTION("Omnivision ov13b10 sensor driver" ); |
1631 | MODULE_LICENSE("GPL v2" ); |
1632 | |