1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * os05a20 driver
4 *
5 * Copyright (C) 2020 Fuzhou Rockchip Electronics Co., Ltd.
6 *
7 * V0.0X01.0X00 first version.
8 */
9
10 #include <linux/clk.h>
11 #include <linux/device.h>
12 #include <linux/delay.h>
13 #include <linux/gpio/consumer.h>
14 #include <linux/i2c.h>
15 #include <linux/module.h>
16 #include <linux/pm_runtime.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/sysfs.h>
19 #include <linux/slab.h>
20 #include <linux/version.h>
21 #include <linux/rk-camera-module.h>
22 #include <media/media-entity.h>
23 #include <media/v4l2-async.h>
24 #include <media/v4l2-ctrls.h>
25 #include <media/v4l2-subdev.h>
26 #include <linux/pinctrl/consumer.h>
27 #include <linux/rk-preisp.h>
28 #include "../platform/rockchip/isp/rkisp_tb_helper.h"
29
30 #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x01)
31
32 #ifndef V4L2_CID_DIGITAL_GAIN
33 #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
34 #endif
35
36 #define MIPI_FREQ_750M 750000000
37
38 #define PIXEL_RATE_WITH_750M (MIPI_FREQ_750M * 2 / 12 * 4)
39
40 #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
41
42 #define OS05A20_XVCLK_FREQ 24000000
43
44 #define CHIP_ID 0x530541
45 #define OS05A20_REG_CHIP_ID 0x300a
46
47 #define OS05A20_REG_CTRL_MODE 0x0100
48 #define OS05A20_MODE_SW_STANDBY 0x0
49 #define OS05A20_MODE_STREAMING BIT(0)
50
51 #define OS05A20_EXPOSURE_MIN 4
52 #define OS05A20_EXPOSURE_STEP 1
53 #define OS05A20_VTS_MAX 0xffff
54
55 #define OS05A20_REG_EXP_LONG_H 0x3501
56 #define OS05A20_REG_EXP_VS_H 0x3511
57
58 #define OS05A20_REG_AGAIN_LONG_H 0x3508
59 #define OS05A20_REG_AGAIN_VS_H 0x350c
60
61 #define OS05A20_REG_DGAIN_LONG_H 0x350a
62 #define OS05A20_REG_DGAIN_VS_H 0x350e
63 #define OS05A20_GAIN_MIN 0x80
64 #define OS05A20_GAIN_MAX 0x3D9CC
65 #define OS05A20_GAIN_STEP 1
66 #define OS05A20_GAIN_DEFAULT 0x80
67
68 #define OS05A20_GROUP_UPDATE_ADDRESS 0x3208
69 #define OS05A20_GROUP_UPDATE_START_DATA 0x00
70 #define OS05A20_GROUP_UPDATE_END_DATA 0x10
71 #define OS05A20_GROUP_UPDATE_LAUNCH 0xA0
72
73 #define OS05A20_SOFTWARE_RESET_REG 0x0103
74
75 #define OS05A20_REG_TEST_PATTERN 0x5081
76 #define OS05A20_TEST_PATTERN_ENABLE 0x80
77 #define OS05A20_TEST_PATTERN_DISABLE 0x0
78
79 #define OS05A20_REG_VTS 0x380e
80
81 #define REG_NULL 0xFFFF
82
83 #define OS05A20_REG_VALUE_08BIT 1
84 #define OS05A20_REG_VALUE_16BIT 2
85 #define OS05A20_REG_VALUE_24BIT 3
86
87 #define OS05A20_LANES 4
88
89 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
90 #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
91
92 #define OS05A20_NAME "os05a20"
93
94 #define USED_SYS_DEBUG
95
96 static const char * const os05a20_supply_names[] = {
97 "avdd", /* Analog power */
98 "dovdd", /* Digital I/O power */
99 "dvdd", /* Digital core power */
100 };
101
102 #define OS05A20_NUM_SUPPLIES ARRAY_SIZE(os05a20_supply_names)
103
104 #define OS05A20_FLIP_REG 0x3820
105 #define OS05A20_MIRROR_REG 0x3821
106 #define MIRROR_BIT_MASK BIT(2)
107 #define FLIP_BIT_MASK BIT(2)
108
109 struct regval {
110 u16 addr;
111 u8 val;
112 };
113
114 struct os05a20_mode {
115 u32 bus_fmt;
116 u32 width;
117 u32 height;
118 struct v4l2_fract max_fps;
119 u32 hts_def;
120 u32 vts_def;
121 u32 exp_def;
122 const struct regval *reg_list;
123 u32 hdr_mode;
124 u32 vc[PAD_MAX];
125 };
126
127 struct os05a20 {
128 struct i2c_client *client;
129 struct clk *xvclk;
130 struct gpio_desc *power_gpio;
131 struct gpio_desc *reset_gpio;
132 struct gpio_desc *pwdn_gpio;
133 struct regulator_bulk_data supplies[OS05A20_NUM_SUPPLIES];
134
135 struct pinctrl *pinctrl;
136 struct pinctrl_state *pins_default;
137 struct pinctrl_state *pins_sleep;
138
139 struct v4l2_subdev subdev;
140 struct media_pad pad;
141 struct v4l2_ctrl_handler ctrl_handler;
142 struct v4l2_ctrl *exposure;
143 struct v4l2_ctrl *anal_gain;
144 struct v4l2_ctrl *digi_gain;
145 struct v4l2_ctrl *hblank;
146 struct v4l2_ctrl *vblank;
147 struct v4l2_ctrl *test_pattern;
148 struct v4l2_ctrl *pixel_rate;
149 struct v4l2_ctrl *link_freq;
150 struct v4l2_ctrl *h_flip;
151 struct v4l2_ctrl *v_flip;
152 struct mutex mutex;
153 bool streaming;
154 bool power_on;
155 const struct os05a20_mode *cur_mode;
156 u32 cfg_num;
157 u32 module_index;
158 const char *module_facing;
159 const char *module_name;
160 const char *len_name;
161 bool has_init_exp;
162 struct preisp_hdrae_exp_s init_hdrae_exp;
163 bool is_thunderboot;
164 bool is_thunderboot_ng;
165 bool is_first_streamoff;
166 };
167
168 #define to_os05a20(sd) container_of(sd, struct os05a20, subdev)
169
170 /*
171 * Xclk 24Mhz
172 */
173 static const struct regval os05a20_global_regs[] = {
174 {REG_NULL, 0x00},
175 };
176
177 static const struct regval os05a20_linear12bit_2688x1944_regs[] = {
178 {0x0103, 0x01},
179 {0x0303, 0x01},
180 {0x0305, 0x5e},
181 {0x0306, 0x00},
182 {0x0307, 0x00},
183 {0x0308, 0x03},
184 {0x0309, 0x04},
185 {0x032a, 0x00},
186 {0x031e, 0x0a},
187 {0x0325, 0x48},
188 {0x0328, 0x07},
189 {0x300d, 0x11},
190 {0x300e, 0x11},
191 {0x300f, 0x11},
192 {0x3010, 0x01},
193 {0x3012, 0x41},
194 {0x3016, 0xf0},
195 {0x3018, 0xf0},
196 {0x3028, 0xf0},
197 {0x301e, 0x98},
198 {0x3010, 0x04},
199 {0x3011, 0x06},
200 {0x3031, 0xa9},
201 {0x3103, 0x48},
202 {0x3104, 0x01},
203 {0x3106, 0x10},
204 {0x3400, 0x04},
205 {0x3025, 0x03},
206 {0x3425, 0x51},
207 {0x3428, 0x01},
208 {0x3406, 0x08},
209 {0x3408, 0x03},
210 {0x3501, 0x09},
211 {0x3502, 0xa0},
212 {0x3505, 0x83},
213 {0x3508, 0x00},
214 {0x3509, 0x80},
215 {0x350a, 0x04},
216 {0x350b, 0x00},
217 {0x350c, 0x00},
218 {0x350d, 0x80},
219 {0x350e, 0x04},
220 {0x350f, 0x00},
221 {0x3600, 0x00},
222 {0x3626, 0xff},
223 {0x3605, 0x50},
224 {0x3609, 0xdb},
225 {0x3610, 0x69},
226 {0x360c, 0x01},
227 {0x3628, 0xa4},
228 {0x3629, 0x6a},
229 {0x362d, 0x10},
230 {0x3660, 0xd3},
231 {0x3661, 0x06},
232 {0x3662, 0x00},
233 {0x3663, 0x28},
234 {0x3664, 0x0d},
235 {0x366a, 0x38},
236 {0x366b, 0xa0},
237 {0x366d, 0x00},
238 {0x366e, 0x00},
239 {0x3680, 0x00},
240 {0x36c0, 0x00},
241 {0x3621, 0x81},
242 {0x3634, 0x31},
243 {0x3620, 0x00},
244 {0x3622, 0x00},
245 {0x362a, 0xd0},
246 {0x362e, 0x8c},
247 {0x362f, 0x98},
248 {0x3630, 0xb0},
249 {0x3631, 0xd7},
250 {0x3701, 0x0f},
251 {0x3737, 0x02},
252 {0x3741, 0x04},
253 {0x373c, 0x0f},
254 {0x373b, 0x02},
255 {0x3705, 0x00},
256 {0x3706, 0xa0},
257 {0x370a, 0x01},
258 {0x370b, 0xc8},
259 {0x3709, 0x4a},
260 {0x3714, 0x21},
261 {0x371c, 0x00},
262 {0x371d, 0x08},
263 {0x375e, 0x0e},
264 {0x3760, 0x13},
265 {0x3776, 0x10},
266 {0x3781, 0x02},
267 {0x3782, 0x04},
268 {0x3783, 0x02},
269 {0x3784, 0x08},
270 {0x3785, 0x08},
271 {0x3788, 0x01},
272 {0x3789, 0x01},
273 {0x3797, 0x84},
274 {0x3798, 0x01},
275 {0x3799, 0x00},
276 {0x3761, 0x02},
277 {0x3762, 0x0d},
278 {0x3800, 0x00},
279 {0x3801, 0x00},
280 {0x3802, 0x00},
281 {0x3803, 0x0c},
282 {0x3804, 0x0e},
283 {0x3805, 0xff},
284 {0x3806, 0x08},
285 {0x3807, 0x6f},
286 {0x3808, 0x0a},
287 {0x3809, 0x80},
288 {0x380a, 0x07},
289 {0x380b, 0x98},
290 {0x380c, 0x02},
291 {0x380d, 0xd0},
292 {0x380e, 0x09},
293 {0x380f, 0xc0},
294 {0x3813, 0x04},
295 {0x3814, 0x01},
296 {0x3815, 0x01},
297 {0x3816, 0x01},
298 {0x3817, 0x01},
299 {0x381c, 0x00},
300 {0x3820, 0x00},
301 {0x3821, 0x04},
302 {0x3823, 0x18},
303 {0x3826, 0x00},
304 {0x3827, 0x01},
305 {0x3832, 0x02},
306 {0x383c, 0x48},
307 {0x383d, 0xff},
308 {0x3843, 0x20},
309 {0x382d, 0x08},
310 {0x3d85, 0x0b},
311 {0x3d84, 0x40},
312 {0x3d8c, 0x63},
313 {0x3d8d, 0x00},
314 {0x4000, 0x78},
315 {0x4001, 0x2b},
316 {0x4005, 0x40},
317 {0x4028, 0x2f},
318 {0x400a, 0x01},
319 {0x4010, 0x12},
320 {0x4008, 0x02},
321 {0x4009, 0x0d},
322 {0x401a, 0x58},
323 {0x4050, 0x00},
324 {0x4051, 0x01},
325 {0x4052, 0x00},
326 {0x4053, 0x80},
327 {0x4054, 0x00},
328 {0x4055, 0x80},
329 {0x4056, 0x00},
330 {0x4057, 0x80},
331 {0x4058, 0x00},
332 {0x4059, 0x80},
333 {0x430b, 0xff},
334 {0x430c, 0xff},
335 {0x430d, 0x00},
336 {0x430e, 0x00},
337 {0x4501, 0x18},
338 {0x4502, 0x00},
339 {0x4600, 0x00},
340 {0x4601, 0x10},
341 {0x4603, 0x01},
342 {0x4643, 0x00},
343 {0x4640, 0x01},
344 {0x4641, 0x04},
345 {0x480e, 0x00},
346 {0x4813, 0x00},
347 {0x4815, 0x2b},
348 {0x486e, 0x36},
349 {0x486f, 0x84},
350 {0x4860, 0x00},
351 {0x4861, 0xa0},
352 {0x484b, 0x05},
353 {0x4850, 0x00},
354 {0x4851, 0xaa},
355 {0x4852, 0xff},
356 {0x4853, 0x8a},
357 {0x4854, 0x08},
358 {0x4855, 0x30},
359 {0x4800, 0x00},
360 {0x4837, 0x0a},
361 {0x484a, 0x3f},
362 {0x5000, 0xc9},
363 {0x5001, 0x43},
364 {0x5002, 0x00},
365 {0x5211, 0x03},
366 {0x5291, 0x03},
367 {0x520d, 0x0f},
368 {0x520e, 0xfd},
369 {0x520f, 0xa5},
370 {0x5210, 0xa5},
371 {0x528d, 0x0f},
372 {0x528e, 0xfd},
373 {0x528f, 0xa5},
374 {0x5290, 0xa5},
375 {0x5004, 0x40},
376 {0x5005, 0x00},
377 {0x5180, 0x00},
378 {0x5181, 0x10},
379 {0x5182, 0x0f},
380 {0x5183, 0xff},
381 {0x580b, 0x03},
382 {0x4d00, 0x03},
383 {0x4d01, 0xe9},
384 {0x4d02, 0xba},
385 {0x4d03, 0x66},
386 {0x4d04, 0x46},
387 {0x4d05, 0xa5},
388 {0x3603, 0x3c},
389 {0x3703, 0x26},
390 {0x3709, 0x49},
391 {0x3708, 0x2d},
392 {0x3719, 0x1c},
393 {0x371a, 0x06},
394 {0x4000, 0x79},
395 {0x380c, 0x04},
396 {0x380d, 0x04},
397 {0x380e, 0x0d},
398 {0x380f, 0xad},
399 {0x3501, 0x0d},
400 {0x3502, 0xa5},
401 {0x4603, 0x00},
402 {REG_NULL, 0x00},
403 };
404
405 static const struct regval os05a20_hdr12bit_2688x1944_regs[] = {
406 {0x0100, 0x00},
407 {0x0103, 0x01},
408 {0x0303, 0x01},
409 {0x0305, 0x5e},
410 {0x0306, 0x00},
411 {0x0307, 0x00},
412 {0x0308, 0x03},
413 {0x0309, 0x04},
414 {0x032a, 0x00},
415 {0x031e, 0x0a},
416 {0x0325, 0x48},
417 {0x0328, 0x07},
418 {0x300d, 0x11},
419 {0x300e, 0x11},
420 {0x300f, 0x11},
421 {0x3026, 0x00},
422 {0x3027, 0x00},
423 {0x3010, 0x01},
424 {0x3012, 0x41},
425 {0x3016, 0xf0},
426 {0x3018, 0xf0},
427 {0x3028, 0xf0},
428 {0x301e, 0x98},
429 {0x3010, 0x01},
430 {0x3011, 0x04},
431 {0x3031, 0xa9},
432 {0x3103, 0x48},
433 {0x3104, 0x01},
434 {0x3106, 0x10},
435 {0x3501, 0x09},
436 {0x3502, 0xa0},
437 {0x3505, 0x83},
438 {0x3508, 0x00},
439 {0x3509, 0x80},
440 {0x350a, 0x04},
441 {0x350b, 0x00},
442 {0x350c, 0x00},
443 {0x350d, 0x80},
444 {0x350e, 0x04},
445 {0x350f, 0x00},
446 {0x3600, 0x00},
447 {0x3626, 0xff},
448 {0x3605, 0x50},
449 {0x3609, 0xb5},
450 {0x3610, 0x69},
451 {0x360c, 0x01},
452 {0x3628, 0xa4},
453 {0x3629, 0x6a},
454 {0x362d, 0x10},
455 {0x3660, 0x42},
456 {0x3661, 0x07},
457 {0x3662, 0x00},
458 {0x3663, 0x28},
459 {0x3664, 0x0d},
460 {0x366a, 0x38},
461 {0x366b, 0xa0},
462 {0x366d, 0x00},
463 {0x366e, 0x00},
464 {0x3680, 0x00},
465 {0x36c0, 0x00},
466 {0x3621, 0x81},
467 {0x3634, 0x31},
468 {0x3620, 0x00},
469 {0x3622, 0x00},
470 {0x362a, 0xd0},
471 {0x362e, 0x8c},
472 {0x362f, 0x98},
473 {0x3630, 0xb0},
474 {0x3631, 0xd7},
475 {0x3701, 0x0f},
476 {0x3737, 0x02},
477 {0x3740, 0x18},
478 {0x3741, 0x04},
479 {0x373c, 0x0f},
480 {0x373b, 0x02},
481 {0x3705, 0x00},
482 {0x3706, 0x50},
483 {0x370a, 0x00},
484 {0x370b, 0xe4},
485 {0x3709, 0x4a},
486 {0x3714, 0x21},
487 {0x371c, 0x00},
488 {0x371d, 0x08},
489 {0x375e, 0x0e},
490 {0x3760, 0x13},
491 {0x3776, 0x10},
492 {0x3781, 0x02},
493 {0x3782, 0x04},
494 {0x3783, 0x02},
495 {0x3784, 0x08},
496 {0x3785, 0x08},
497 {0x3788, 0x01},
498 {0x3789, 0x01},
499 {0x3797, 0x04},
500 {0x3798, 0x01},
501 {0x3799, 0x00},
502 {0x3761, 0x02},
503 {0x3762, 0x0d},
504 {0x3800, 0x00},
505 {0x3801, 0x00},
506 {0x3802, 0x00},
507 {0x3803, 0x0c},
508 {0x3804, 0x0e},
509 {0x3805, 0xff},
510 {0x3806, 0x08},
511 {0x3807, 0x6f},
512 {0x3808, 0x0a},
513 {0x3809, 0x80},
514 {0x380a, 0x07},
515 {0x380b, 0x98},
516 {0x380c, 0x02},
517 {0x380d, 0xd0},
518 {0x380e, 0x09},
519 {0x380f, 0xc0},
520 {0x3811, 0x10},
521 {0x3813, 0x04},
522 {0x3814, 0x01},
523 {0x3815, 0x01},
524 {0x3816, 0x01},
525 {0x3817, 0x01},
526 {0x381c, 0x08},
527 {0x3820, 0x00},
528 {0x3821, 0x24},
529 {0x3822, 0x54},
530 {0x3823, 0x08},
531 {0x3826, 0x00},
532 {0x3827, 0x01},
533 {0x3833, 0x01},
534 {0x3832, 0x02},
535 {0x383c, 0x48},
536 {0x383d, 0xff},
537 {0x3843, 0x20},
538 {0x382d, 0x08},
539 {0x3d85, 0x0b},
540 {0x3d84, 0x40},
541 {0x3d8c, 0x63},
542 {0x3d8d, 0x00},
543 {0x4000, 0x78},
544 {0x4001, 0x2b},
545 {0x4004, 0x00},
546 {0x4005, 0x40},
547 {0x4028, 0x2f},
548 {0x400a, 0x01},
549 {0x4010, 0x12},
550 {0x4008, 0x02},
551 {0x4009, 0x0d},
552 {0x401a, 0x58},
553 {0x4050, 0x00},
554 {0x4051, 0x01},
555 {0x4052, 0x00},
556 {0x4053, 0x80},
557 {0x4054, 0x00},
558 {0x4055, 0x80},
559 {0x4056, 0x00},
560 {0x4057, 0x80},
561 {0x4058, 0x00},
562 {0x4059, 0x80},
563 {0x430b, 0xff},
564 {0x430c, 0xff},
565 {0x430d, 0x00},
566 {0x430e, 0x00},
567 {0x4501, 0x18},
568 {0x4502, 0x00},
569 {0x4643, 0x00},
570 {0x4640, 0x01},
571 {0x4641, 0x04},
572 {0x480e, 0x04},
573 {0x4813, 0x98},
574 {0x4815, 0x2b},
575 {0x486e, 0x36},
576 {0x486f, 0x84},
577 {0x4860, 0x00},
578 {0x4861, 0xa0},
579 {0x484b, 0x05},
580 {0x4850, 0x00},
581 {0x4851, 0xaa},
582 {0x4852, 0xff},
583 {0x4853, 0x8a},
584 {0x4854, 0x08},
585 {0x4855, 0x30},
586 {0x4800, 0x60},
587 {0x4837, 0x0a},
588 {0x484a, 0x3f},
589 {0x5000, 0xc9},
590 {0x5001, 0x43},
591 {0x5002, 0x00},
592 {0x5211, 0x03},
593 {0x5291, 0x03},
594 {0x520d, 0x0f},
595 {0x520e, 0xfd},
596 {0x520f, 0xa5},
597 {0x5210, 0xa5},
598 {0x528d, 0x0f},
599 {0x528e, 0xfd},
600 {0x528f, 0xa5},
601 {0x5290, 0xa5},
602 {0x5004, 0x40},
603 {0x5005, 0x00},
604 {0x5180, 0x00},
605 {0x5181, 0x10},
606 {0x5182, 0x0f},
607 {0x5183, 0xff},
608 {0x580b, 0x03},
609 {0x4d00, 0x03},
610 {0x4d01, 0xe9},
611 {0x4d02, 0xba},
612 {0x4d03, 0x66},
613 {0x4d04, 0x46},
614 {0x4d05, 0xa5},
615 {0x3603, 0x3c},
616 {0x3703, 0x26},
617 {0x3709, 0x49},
618 {0x3708, 0x2d},
619 {0x3719, 0x1c},
620 {0x371a, 0x06},
621 {0x4000, 0x79},
622 {0x380c, 0x02},
623 {0x380d, 0xd0},
624 {0x380e, 0x09},
625 {0x380f, 0xc4},
626 {0x3501, 0x08},
627 {0x3502, 0xc4},
628 {0x3511, 0x00},
629 {0x3512, 0x20},
630 {REG_NULL, 0x00},
631 };
632
633 /*
634 * The width and height must be configured to be
635 * the same as the current output resolution of the sensor.
636 * The input width of the isp needs to be 16 aligned.
637 * The input height of the isp needs to be 8 aligned.
638 * If the width or height does not meet the alignment rules,
639 * you can configure the cropping parameters with the following function to
640 * crop out the appropriate resolution.
641 * struct v4l2_subdev_pad_ops {
642 * .get_selection
643 * }
644 */
645 static const struct os05a20_mode supported_modes[] = {
646 {
647 .bus_fmt = MEDIA_BUS_FMT_SBGGR12_1X12,
648 .width = 2688,
649 .height = 1944,
650 .max_fps = {
651 .numerator = 10000,
652 .denominator = 300000,
653 },
654 .exp_def = 0x09a0,
655 .hts_def = 0x02d0 * 4,
656 .vts_def = 0x0dad,
657 .reg_list = os05a20_linear12bit_2688x1944_regs,
658 .hdr_mode = NO_HDR,
659 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
660 },
661 {
662 .bus_fmt = MEDIA_BUS_FMT_SBGGR12_1X12,
663 .width = 2688,
664 .height = 1944,
665 .max_fps = {
666 .numerator = 10000,
667 .denominator = 300000,
668 },
669 .exp_def = 0x09a0,
670 .hts_def = 0x02d0 * 4,
671 .vts_def = 0x09c4,
672 .reg_list = os05a20_hdr12bit_2688x1944_regs,
673 .hdr_mode = HDR_X2,
674 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_1,
675 .vc[PAD1] = V4L2_MBUS_CSI2_CHANNEL_0,//L->csi wr0
676 .vc[PAD2] = V4L2_MBUS_CSI2_CHANNEL_1,
677 .vc[PAD3] = V4L2_MBUS_CSI2_CHANNEL_1,//M->csi wr2
678 },
679 };
680
681 static const s64 link_freq_menu_items[] = {
682 MIPI_FREQ_750M,
683 };
684
685 static const char * const os05a20_test_pattern_menu[] = {
686 "Disabled",
687 "Vertical Color Bar Type 1",
688 "Vertical Color Bar Type 2",
689 "Vertical Color Bar Type 3",
690 "Vertical Color Bar Type 4"
691 };
692
693 static int __os05a20_power_on(struct os05a20 *os05a20);
694
695 /* Write registers up to 4 at a time */
os05a20_write_reg(struct i2c_client * client,u16 reg,u32 len,u32 val)696 static int os05a20_write_reg(struct i2c_client *client, u16 reg,
697 u32 len, u32 val)
698 {
699 u32 buf_i, val_i;
700 u8 buf[6];
701 u8 *val_p;
702 __be32 val_be;
703
704 if (len > 4)
705 return -EINVAL;
706
707 buf[0] = reg >> 8;
708 buf[1] = reg & 0xff;
709
710 val_be = cpu_to_be32(val);
711 val_p = (u8 *)&val_be;
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, len + 2) != len + 2)
719 return -EIO;
720
721 return 0;
722 }
723
os05a20_write_array(struct i2c_client * client,const struct regval * regs)724 static int os05a20_write_array(struct i2c_client *client,
725 const struct regval *regs)
726 {
727 u32 i;
728 int ret = 0;
729
730 for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
731 ret |= os05a20_write_reg(client, regs[i].addr,
732 OS05A20_REG_VALUE_08BIT, regs[i].val);
733 }
734 return ret;
735 }
736
737 /* Read registers up to 4 at a time */
os05a20_read_reg(struct i2c_client * client,u16 reg,unsigned int len,u32 * val)738 static int os05a20_read_reg(struct i2c_client *client,
739 u16 reg,
740 unsigned int len,
741 u32 *val)
742 {
743 struct i2c_msg msgs[2];
744 u8 *data_be_p;
745 __be32 data_be = 0;
746 __be16 reg_addr_be = cpu_to_be16(reg);
747 int ret;
748
749 if (len > 4 || !len)
750 return -EINVAL;
751
752 data_be_p = (u8 *)&data_be;
753 /* Write register address */
754 msgs[0].addr = client->addr;
755 msgs[0].flags = 0;
756 msgs[0].len = 2;
757 msgs[0].buf = (u8 *)®_addr_be;
758
759 /* Read data from register */
760 msgs[1].addr = client->addr;
761 msgs[1].flags = I2C_M_RD;
762 msgs[1].len = len;
763 msgs[1].buf = &data_be_p[4 - len];
764
765 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
766 if (ret != ARRAY_SIZE(msgs))
767 return -EIO;
768
769 *val = be32_to_cpu(data_be);
770
771 return 0;
772 }
773
os05a20_get_reso_dist(const struct os05a20_mode * mode,struct v4l2_mbus_framefmt * framefmt)774 static int os05a20_get_reso_dist(const struct os05a20_mode *mode,
775 struct v4l2_mbus_framefmt *framefmt)
776 {
777 return abs(mode->width - framefmt->width) +
778 abs(mode->height - framefmt->height);
779 }
780
781 static const struct os05a20_mode *
os05a20_find_best_fit(struct os05a20 * os05a20,struct v4l2_subdev_format * fmt)782 os05a20_find_best_fit(struct os05a20 *os05a20, struct v4l2_subdev_format *fmt)
783 {
784 struct v4l2_mbus_framefmt *framefmt = &fmt->format;
785 int dist;
786 int cur_best_fit = 0;
787 int cur_best_fit_dist = -1;
788 unsigned int i;
789
790 for (i = 0; i < os05a20->cfg_num; i++) {
791 dist = os05a20_get_reso_dist(&supported_modes[i], framefmt);
792 if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) &&
793 (supported_modes[i].bus_fmt == framefmt->code)) {
794 cur_best_fit_dist = dist;
795 cur_best_fit = i;
796 }
797 }
798
799 return &supported_modes[cur_best_fit];
800 }
801
os05a20_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)802 static int os05a20_set_fmt(struct v4l2_subdev *sd,
803 struct v4l2_subdev_pad_config *cfg,
804 struct v4l2_subdev_format *fmt)
805 {
806 struct os05a20 *os05a20 = to_os05a20(sd);
807 const struct os05a20_mode *mode;
808 s64 h_blank, vblank_def;
809
810 mutex_lock(&os05a20->mutex);
811
812 mode = os05a20_find_best_fit(os05a20, fmt);
813 fmt->format.code = mode->bus_fmt;
814 fmt->format.width = mode->width;
815 fmt->format.height = mode->height;
816 fmt->format.field = V4L2_FIELD_NONE;
817 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
818 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
819 *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
820 #else
821 mutex_unlock(&os05a20->mutex);
822 return -ENOTTY;
823 #endif
824 } else {
825 os05a20->cur_mode = mode;
826 h_blank = mode->hts_def - mode->width;
827 __v4l2_ctrl_modify_range(os05a20->hblank, h_blank,
828 h_blank, 1, h_blank);
829 vblank_def = mode->vts_def - mode->height;
830 __v4l2_ctrl_modify_range(os05a20->vblank, vblank_def,
831 OS05A20_VTS_MAX - mode->height,
832 1, vblank_def);
833 }
834
835 mutex_unlock(&os05a20->mutex);
836
837 return 0;
838 }
839
os05a20_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)840 static int os05a20_get_fmt(struct v4l2_subdev *sd,
841 struct v4l2_subdev_pad_config *cfg,
842 struct v4l2_subdev_format *fmt)
843 {
844 struct os05a20 *os05a20 = to_os05a20(sd);
845 const struct os05a20_mode *mode = os05a20->cur_mode;
846
847 mutex_lock(&os05a20->mutex);
848 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
849 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
850 fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
851 #else
852 mutex_unlock(&os05a20->mutex);
853 return -ENOTTY;
854 #endif
855 } else {
856 fmt->format.width = mode->width;
857 fmt->format.height = mode->height;
858 fmt->format.code = mode->bus_fmt;
859 fmt->format.field = V4L2_FIELD_NONE;
860 if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
861 fmt->reserved[0] = mode->vc[fmt->pad];
862 else
863 fmt->reserved[0] = mode->vc[PAD0];
864 }
865 mutex_unlock(&os05a20->mutex);
866
867 return 0;
868 }
869
os05a20_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)870 static int os05a20_enum_mbus_code(struct v4l2_subdev *sd,
871 struct v4l2_subdev_pad_config *cfg,
872 struct v4l2_subdev_mbus_code_enum *code)
873 {
874 struct os05a20 *os05a20 = to_os05a20(sd);
875
876 if (code->index != 0)
877 return -EINVAL;
878 code->code = os05a20->cur_mode->bus_fmt;
879
880 return 0;
881 }
882
os05a20_enum_frame_sizes(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_size_enum * fse)883 static int os05a20_enum_frame_sizes(struct v4l2_subdev *sd,
884 struct v4l2_subdev_pad_config *cfg,
885 struct v4l2_subdev_frame_size_enum *fse)
886 {
887 struct os05a20 *os05a20 = to_os05a20(sd);
888
889 if (fse->index >= os05a20->cfg_num)
890 return -EINVAL;
891
892 if (fse->code != supported_modes[fse->index].bus_fmt)
893 return -EINVAL;
894
895 fse->min_width = supported_modes[fse->index].width;
896 fse->max_width = supported_modes[fse->index].width;
897 fse->max_height = supported_modes[fse->index].height;
898 fse->min_height = supported_modes[fse->index].height;
899
900 return 0;
901 }
902
os05a20_enable_test_pattern(struct os05a20 * os05a20,u32 pattern)903 static int os05a20_enable_test_pattern(struct os05a20 *os05a20, u32 pattern)
904 {
905 u32 val;
906 int ret = 0;
907
908 if (pattern)
909 val = ((pattern - 1) << 2) | OS05A20_TEST_PATTERN_ENABLE;
910 else
911 val = OS05A20_TEST_PATTERN_DISABLE;
912 ret = os05a20_write_reg(os05a20->client, OS05A20_REG_TEST_PATTERN,
913 OS05A20_REG_VALUE_08BIT, val);
914 return ret;
915 }
916
os05a20_g_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_frame_interval * fi)917 static int os05a20_g_frame_interval(struct v4l2_subdev *sd,
918 struct v4l2_subdev_frame_interval *fi)
919 {
920 struct os05a20 *os05a20 = to_os05a20(sd);
921 const struct os05a20_mode *mode = os05a20->cur_mode;
922
923 fi->interval = mode->max_fps;
924
925 return 0;
926 }
927
os05a20_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad_id,struct v4l2_mbus_config * config)928 static int os05a20_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
929 struct v4l2_mbus_config *config)
930 {
931 struct os05a20 *os05a20 = to_os05a20(sd);
932 const struct os05a20_mode *mode = os05a20->cur_mode;
933 u32 val = 0;
934
935 if (mode->hdr_mode == NO_HDR)
936 val = 1 << (OS05A20_LANES - 1) |
937 V4L2_MBUS_CSI2_CHANNEL_0 |
938 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
939 if (mode->hdr_mode == HDR_X2)
940 val = 1 << (OS05A20_LANES - 1) |
941 V4L2_MBUS_CSI2_CHANNEL_0 |
942 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
943 V4L2_MBUS_CSI2_CHANNEL_1;
944
945 config->type = V4L2_MBUS_CSI2_DPHY;
946 config->flags = val;
947
948 return 0;
949 }
950
os05a20_get_module_inf(struct os05a20 * os05a20,struct rkmodule_inf * inf)951 static void os05a20_get_module_inf(struct os05a20 *os05a20,
952 struct rkmodule_inf *inf)
953 {
954 memset(inf, 0, sizeof(*inf));
955 strlcpy(inf->base.sensor, OS05A20_NAME, sizeof(inf->base.sensor));
956 strlcpy(inf->base.module, os05a20->module_name,
957 sizeof(inf->base.module));
958 strlcpy(inf->base.lens, os05a20->len_name, sizeof(inf->base.lens));
959 }
960
os05a20_set_hdrae(struct os05a20 * os05a20,struct preisp_hdrae_exp_s * ae)961 static int os05a20_set_hdrae(struct os05a20 *os05a20,
962 struct preisp_hdrae_exp_s *ae)
963 {
964 u32 m_exp_time, s_exp_time;
965 u32 m_gain, s_gain;
966 u32 m_d_gain = 1024;
967 u32 s_d_gain = 1024;
968 int ret = 0;
969
970 if (!os05a20->has_init_exp && !os05a20->streaming) {
971 os05a20->init_hdrae_exp = *ae;
972 os05a20->has_init_exp = true;
973 dev_dbg(&os05a20->client->dev, "os05a20 don't stream, record exp for hdr!\n");
974 return ret;
975 }
976 m_exp_time = ae->middle_exp_reg;
977 s_exp_time = ae->short_exp_reg;
978 m_gain = ae->middle_gain_reg;
979 s_gain = ae->short_gain_reg;
980 dev_dbg(&os05a20->client->dev,
981 "rev exp req: L_exp: 0x%x, 0x%x, S_exp: 0x%x, 0x%x\n",
982 m_exp_time, m_gain,
983 s_exp_time, s_gain);
984
985 if (m_exp_time <= s_exp_time || m_exp_time < 4 || s_exp_time < 4) {
986 dev_err(&os05a20->client->dev,
987 "long exposure must bigger than short exposure,min exposure is 4 line\n");
988 return -EINVAL;
989 }
990
991 if (m_gain > 1984) {// >15.5x
992 m_d_gain = m_gain * 10 / 155;
993 m_gain = 1984;
994 }
995
996 if (s_gain > 1984) {// >15.5x
997 s_d_gain = s_gain * 10 / 155;
998 s_gain = 1984;
999 }
1000 dev_dbg(&os05a20->client->dev,
1001 "set exp: L_exp: 0x%x, 0x%x 0x%x, S_exp: 0x%x, 0x%x, 0x%x\n",
1002 m_exp_time, m_gain, m_d_gain,
1003 s_exp_time, s_gain, s_d_gain);
1004
1005 ret = os05a20_write_reg(os05a20->client,
1006 OS05A20_GROUP_UPDATE_ADDRESS,
1007 OS05A20_REG_VALUE_08BIT,
1008 OS05A20_GROUP_UPDATE_START_DATA);
1009
1010 ret |= os05a20_write_reg(os05a20->client,
1011 OS05A20_REG_EXP_LONG_H,
1012 OS05A20_REG_VALUE_16BIT,
1013 m_exp_time);
1014 ret |= os05a20_write_reg(os05a20->client,
1015 OS05A20_REG_EXP_VS_H,
1016 OS05A20_REG_VALUE_16BIT,
1017 s_exp_time);
1018
1019 ret |= os05a20_write_reg(os05a20->client,
1020 OS05A20_REG_AGAIN_LONG_H,
1021 OS05A20_REG_VALUE_16BIT,
1022 m_gain & 0x7ff);
1023 ret |= os05a20_write_reg(os05a20->client,
1024 OS05A20_REG_DGAIN_LONG_H,
1025 OS05A20_REG_VALUE_16BIT,
1026 m_d_gain & 0x3fff);
1027
1028 ret |= os05a20_write_reg(os05a20->client,
1029 OS05A20_REG_AGAIN_VS_H,
1030 OS05A20_REG_VALUE_16BIT,
1031 s_gain & 0x7ff);
1032 ret |= os05a20_write_reg(os05a20->client,
1033 OS05A20_REG_DGAIN_VS_H,
1034 OS05A20_REG_VALUE_16BIT,
1035 s_d_gain & 0x3fff);
1036 ret |= os05a20_write_reg(os05a20->client,
1037 OS05A20_GROUP_UPDATE_ADDRESS,
1038 OS05A20_REG_VALUE_08BIT,
1039 OS05A20_GROUP_UPDATE_END_DATA);
1040 ret |= os05a20_write_reg(os05a20->client,
1041 OS05A20_GROUP_UPDATE_ADDRESS,
1042 OS05A20_REG_VALUE_08BIT,
1043 OS05A20_GROUP_UPDATE_LAUNCH);
1044 return ret;
1045 }
1046
os05a20_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)1047 static long os05a20_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1048 {
1049 struct os05a20 *os05a20 = to_os05a20(sd);
1050 struct rkmodule_hdr_cfg *hdr_cfg;
1051 long ret = 0;
1052 u32 i, h, w;
1053 u32 stream = 0;
1054
1055 switch (cmd) {
1056 case PREISP_CMD_SET_HDRAE_EXP:
1057 return os05a20_set_hdrae(os05a20, arg);
1058 case RKMODULE_SET_HDR_CFG:
1059 hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
1060 w = os05a20->cur_mode->width;
1061 h = os05a20->cur_mode->height;
1062 for (i = 0; i < os05a20->cfg_num; i++) {
1063 if (w == supported_modes[i].width &&
1064 h == supported_modes[i].height &&
1065 supported_modes[i].hdr_mode == hdr_cfg->hdr_mode) {
1066 os05a20->cur_mode = &supported_modes[i];
1067 break;
1068 }
1069 }
1070 if (i == os05a20->cfg_num) {
1071 dev_err(&os05a20->client->dev,
1072 "not find hdr mode:%d %dx%d config\n",
1073 hdr_cfg->hdr_mode, w, h);
1074 ret = -EINVAL;
1075 } else {
1076 w = os05a20->cur_mode->hts_def - os05a20->cur_mode->width;
1077 h = os05a20->cur_mode->vts_def - os05a20->cur_mode->height;
1078 __v4l2_ctrl_modify_range(os05a20->hblank, w, w, 1, w);
1079 __v4l2_ctrl_modify_range(os05a20->vblank, h,
1080 OS05A20_VTS_MAX - os05a20->cur_mode->height,
1081 1, h);
1082 dev_info(&os05a20->client->dev,
1083 "sensor mode: %d\n",
1084 os05a20->cur_mode->hdr_mode);
1085 }
1086 break;
1087 case RKMODULE_GET_MODULE_INFO:
1088 os05a20_get_module_inf(os05a20, (struct rkmodule_inf *)arg);
1089 break;
1090 case RKMODULE_GET_HDR_CFG:
1091 hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
1092 hdr_cfg->esp.mode = HDR_NORMAL_VC;
1093 hdr_cfg->hdr_mode = os05a20->cur_mode->hdr_mode;
1094 break;
1095 case RKMODULE_SET_CONVERSION_GAIN:
1096 ret = -EINVAL;
1097 break;
1098 case RKMODULE_SET_QUICK_STREAM:
1099
1100 stream = *((u32 *)arg);
1101
1102 if (stream)
1103 ret = os05a20_write_reg(os05a20->client, OS05A20_REG_CTRL_MODE,
1104 OS05A20_REG_VALUE_08BIT, OS05A20_MODE_STREAMING);
1105 else
1106 ret = os05a20_write_reg(os05a20->client, OS05A20_REG_CTRL_MODE,
1107 OS05A20_REG_VALUE_08BIT, OS05A20_MODE_SW_STANDBY);
1108 break;
1109 default:
1110 ret = -ENOIOCTLCMD;
1111 break;
1112 }
1113
1114 return ret;
1115 }
1116
1117 #ifdef CONFIG_COMPAT
os05a20_compat_ioctl32(struct v4l2_subdev * sd,unsigned int cmd,unsigned long arg)1118 static long os05a20_compat_ioctl32(struct v4l2_subdev *sd,
1119 unsigned int cmd, unsigned long arg)
1120 {
1121 void __user *up = compat_ptr(arg);
1122 struct rkmodule_inf *inf;
1123 struct rkmodule_awb_cfg *cfg;
1124 struct rkmodule_hdr_cfg *hdr;
1125 struct preisp_hdrae_exp_s *hdrae;
1126 long ret;
1127 u32 stream = 0;
1128
1129 switch (cmd) {
1130 case RKMODULE_GET_MODULE_INFO:
1131 inf = kzalloc(sizeof(*inf), GFP_KERNEL);
1132 if (!inf) {
1133 ret = -ENOMEM;
1134 return ret;
1135 }
1136
1137 ret = os05a20_ioctl(sd, cmd, inf);
1138 if (!ret)
1139 ret = copy_to_user(up, inf, sizeof(*inf));
1140 kfree(inf);
1141 break;
1142 case RKMODULE_AWB_CFG:
1143 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
1144 if (!cfg) {
1145 ret = -ENOMEM;
1146 return ret;
1147 }
1148
1149 ret = copy_from_user(cfg, up, sizeof(*cfg));
1150 if (!ret)
1151 ret = os05a20_ioctl(sd, cmd, cfg);
1152 kfree(cfg);
1153 break;
1154 case RKMODULE_GET_HDR_CFG:
1155 hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
1156 if (!hdr) {
1157 ret = -ENOMEM;
1158 return ret;
1159 }
1160
1161 ret = os05a20_ioctl(sd, cmd, hdr);
1162 if (!ret)
1163 ret = copy_to_user(up, hdr, sizeof(*hdr));
1164 kfree(hdr);
1165 break;
1166 case RKMODULE_SET_HDR_CFG:
1167 hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
1168 if (!hdr) {
1169 ret = -ENOMEM;
1170 return ret;
1171 }
1172
1173 ret = copy_from_user(hdr, up, sizeof(*hdr));
1174 if (!ret)
1175 ret = os05a20_ioctl(sd, cmd, hdr);
1176 kfree(hdr);
1177 break;
1178 case PREISP_CMD_SET_HDRAE_EXP:
1179 hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
1180 if (!hdrae) {
1181 ret = -ENOMEM;
1182 return ret;
1183 }
1184
1185 ret = copy_from_user(hdrae, up, sizeof(*hdrae));
1186 if (!ret)
1187 ret = os05a20_ioctl(sd, cmd, hdrae);
1188 kfree(hdrae);
1189 break;
1190 case RKMODULE_SET_CONVERSION_GAIN:
1191 ret = -EINVAL;
1192 break;
1193 case RKMODULE_SET_QUICK_STREAM:
1194 ret = copy_from_user(&stream, up, sizeof(u32));
1195 if (!ret)
1196 ret = os05a20_ioctl(sd, cmd, &stream);
1197 break;
1198 default:
1199 ret = -ENOIOCTLCMD;
1200 break;
1201 }
1202
1203 return ret;
1204 }
1205 #endif
1206
__os05a20_start_stream(struct os05a20 * os05a20)1207 static int __os05a20_start_stream(struct os05a20 *os05a20)
1208 {
1209 int ret;
1210
1211 if (!os05a20->is_thunderboot) {
1212 ret = os05a20_write_array(os05a20->client, os05a20_global_regs);
1213 if (ret) {
1214 dev_err(&os05a20->client->dev,
1215 "could not set init registers\n");
1216 return ret;
1217 }
1218
1219 ret = os05a20_write_array(os05a20->client, os05a20->cur_mode->reg_list);
1220 if (ret)
1221 return ret;
1222 }
1223
1224 /* In case these controls are set before streaming */
1225 ret = __v4l2_ctrl_handler_setup(&os05a20->ctrl_handler);
1226 if (ret)
1227 return ret;
1228 if (os05a20->has_init_exp && os05a20->cur_mode->hdr_mode != NO_HDR) {
1229 ret = os05a20_ioctl(&os05a20->subdev,
1230 PREISP_CMD_SET_HDRAE_EXP,
1231 &os05a20->init_hdrae_exp);
1232 if (ret) {
1233 dev_err(&os05a20->client->dev,
1234 "init exp fail in hdr mode\n");
1235 return ret;
1236 }
1237 }
1238 return os05a20_write_reg(os05a20->client, OS05A20_REG_CTRL_MODE,
1239 OS05A20_REG_VALUE_08BIT, OS05A20_MODE_STREAMING);
1240 }
1241
__os05a20_stop_stream(struct os05a20 * os05a20)1242 static int __os05a20_stop_stream(struct os05a20 *os05a20)
1243 {
1244 os05a20->has_init_exp = false;
1245 if (os05a20->is_thunderboot)
1246 os05a20->is_first_streamoff = true;
1247 return os05a20_write_reg(os05a20->client, OS05A20_REG_CTRL_MODE,
1248 OS05A20_REG_VALUE_08BIT, OS05A20_MODE_SW_STANDBY);
1249 }
1250
os05a20_s_stream(struct v4l2_subdev * sd,int on)1251 static int os05a20_s_stream(struct v4l2_subdev *sd, int on)
1252 {
1253 struct os05a20 *os05a20 = to_os05a20(sd);
1254 struct i2c_client *client = os05a20->client;
1255 int ret = 0;
1256
1257 mutex_lock(&os05a20->mutex);
1258 on = !!on;
1259 if (on == os05a20->streaming)
1260 goto unlock_and_return;
1261
1262 if (on) {
1263 if (os05a20->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
1264 os05a20->is_thunderboot = false;
1265 __os05a20_power_on(os05a20);
1266 }
1267 ret = pm_runtime_get_sync(&client->dev);
1268 if (ret < 0) {
1269 pm_runtime_put_noidle(&client->dev);
1270 goto unlock_and_return;
1271 }
1272
1273 ret = __os05a20_start_stream(os05a20);
1274 if (ret) {
1275 v4l2_err(sd, "start stream failed while write regs\n");
1276 pm_runtime_put(&client->dev);
1277 goto unlock_and_return;
1278 }
1279 } else {
1280 __os05a20_stop_stream(os05a20);
1281 pm_runtime_put(&client->dev);
1282 }
1283
1284 os05a20->streaming = on;
1285
1286 unlock_and_return:
1287 mutex_unlock(&os05a20->mutex);
1288
1289 return ret;
1290 }
1291
os05a20_s_power(struct v4l2_subdev * sd,int on)1292 static int os05a20_s_power(struct v4l2_subdev *sd, int on)
1293 {
1294 struct os05a20 *os05a20 = to_os05a20(sd);
1295 struct i2c_client *client = os05a20->client;
1296 int ret = 0;
1297
1298 mutex_lock(&os05a20->mutex);
1299
1300 /* If the power state is not modified - no work to do. */
1301 if (os05a20->power_on == !!on)
1302 goto unlock_and_return;
1303
1304 if (on) {
1305 ret = pm_runtime_get_sync(&client->dev);
1306 if (ret < 0) {
1307 pm_runtime_put_noidle(&client->dev);
1308 goto unlock_and_return;
1309 }
1310
1311 if (!os05a20->is_thunderboot) {
1312 ret |= os05a20_write_reg(os05a20->client,
1313 OS05A20_SOFTWARE_RESET_REG,
1314 OS05A20_REG_VALUE_08BIT,
1315 0x01);
1316 usleep_range(100, 200);
1317 }
1318
1319 os05a20->power_on = true;
1320 } else {
1321 pm_runtime_put(&client->dev);
1322 os05a20->power_on = false;
1323 }
1324
1325 unlock_and_return:
1326 mutex_unlock(&os05a20->mutex);
1327
1328 return ret;
1329 }
1330
1331 /* Calculate the delay in us by clock rate and clock cycles */
os05a20_cal_delay(u32 cycles)1332 static inline u32 os05a20_cal_delay(u32 cycles)
1333 {
1334 return DIV_ROUND_UP(cycles, OS05A20_XVCLK_FREQ / 1000 / 1000);
1335 }
1336
__os05a20_power_on(struct os05a20 * os05a20)1337 static int __os05a20_power_on(struct os05a20 *os05a20)
1338 {
1339 int ret;
1340 u32 delay_us;
1341 struct device *dev = &os05a20->client->dev;
1342
1343 if (os05a20->is_thunderboot)
1344 return 0;
1345
1346 if (!IS_ERR_OR_NULL(os05a20->pins_default)) {
1347 ret = pinctrl_select_state(os05a20->pinctrl,
1348 os05a20->pins_default);
1349 if (ret < 0)
1350 dev_err(dev, "could not set pins\n");
1351 }
1352 ret = clk_set_rate(os05a20->xvclk, OS05A20_XVCLK_FREQ);
1353 if (ret < 0)
1354 dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
1355 if (clk_get_rate(os05a20->xvclk) != OS05A20_XVCLK_FREQ)
1356 dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
1357 ret = clk_prepare_enable(os05a20->xvclk);
1358 if (ret < 0) {
1359 dev_err(dev, "Failed to enable xvclk\n");
1360 return ret;
1361 }
1362 if (!IS_ERR(os05a20->power_gpio)) {
1363 gpiod_direction_output(os05a20->power_gpio, 1);
1364 usleep_range(6000, 8000);
1365 }
1366 if (!IS_ERR(os05a20->reset_gpio))
1367 gpiod_direction_output(os05a20->reset_gpio, 1);
1368
1369 ret = regulator_bulk_enable(OS05A20_NUM_SUPPLIES, os05a20->supplies);
1370 if (ret < 0) {
1371 dev_err(dev, "Failed to enable regulators\n");
1372 goto disable_clk;
1373 }
1374
1375 if (!IS_ERR(os05a20->reset_gpio))
1376 gpiod_direction_output(os05a20->reset_gpio, 0);
1377
1378 usleep_range(500, 1000);
1379 if (!IS_ERR(os05a20->pwdn_gpio))
1380 gpiod_direction_output(os05a20->pwdn_gpio, 1);
1381 /*
1382 * There is no need to wait for the delay of RC circuit
1383 * if the reset signal is directly controlled by GPIO.
1384 */
1385 if (!IS_ERR(os05a20->reset_gpio))
1386 usleep_range(6000, 8000);
1387 else
1388 usleep_range(12000, 16000);
1389
1390 /* 8192 cycles prior to first SCCB transaction */
1391 delay_us = os05a20_cal_delay(8192);
1392 usleep_range(delay_us, delay_us * 2);
1393
1394 return 0;
1395
1396 disable_clk:
1397 clk_disable_unprepare(os05a20->xvclk);
1398
1399 return ret;
1400 }
1401
__os05a20_power_off(struct os05a20 * os05a20)1402 static void __os05a20_power_off(struct os05a20 *os05a20)
1403 {
1404 int ret;
1405 struct device *dev = &os05a20->client->dev;
1406
1407 if (os05a20->is_thunderboot) {
1408 if (os05a20->is_first_streamoff) {
1409 os05a20->is_thunderboot = false;
1410 os05a20->is_first_streamoff = false;
1411 } else {
1412 return;
1413 }
1414 }
1415
1416 if (!IS_ERR(os05a20->pwdn_gpio))
1417 gpiod_direction_output(os05a20->pwdn_gpio, 0);
1418
1419 clk_disable_unprepare(os05a20->xvclk);
1420
1421 if (!IS_ERR(os05a20->reset_gpio))
1422 gpiod_direction_output(os05a20->reset_gpio, 0);
1423 if (!IS_ERR(os05a20->power_gpio))
1424 gpiod_direction_output(os05a20->power_gpio, 0);
1425 if (!IS_ERR_OR_NULL(os05a20->pins_sleep)) {
1426 ret = pinctrl_select_state(os05a20->pinctrl,
1427 os05a20->pins_sleep);
1428 if (ret < 0)
1429 dev_dbg(dev, "could not set pins\n");
1430 }
1431
1432 if (os05a20->is_thunderboot_ng) {
1433 os05a20->is_thunderboot_ng = false;
1434 regulator_bulk_disable(OS05A20_NUM_SUPPLIES, os05a20->supplies);
1435 }
1436 }
1437
os05a20_runtime_resume(struct device * dev)1438 static int os05a20_runtime_resume(struct device *dev)
1439 {
1440 struct i2c_client *client = to_i2c_client(dev);
1441 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1442 struct os05a20 *os05a20 = to_os05a20(sd);
1443
1444 return __os05a20_power_on(os05a20);
1445 }
1446
os05a20_runtime_suspend(struct device * dev)1447 static int os05a20_runtime_suspend(struct device *dev)
1448 {
1449 struct i2c_client *client = to_i2c_client(dev);
1450 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1451 struct os05a20 *os05a20 = to_os05a20(sd);
1452
1453 __os05a20_power_off(os05a20);
1454
1455 return 0;
1456 }
1457
1458 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
os05a20_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)1459 static int os05a20_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1460 {
1461 struct os05a20 *os05a20 = to_os05a20(sd);
1462 struct v4l2_mbus_framefmt *try_fmt =
1463 v4l2_subdev_get_try_format(sd, fh->pad, 0);
1464 const struct os05a20_mode *def_mode = &supported_modes[0];
1465
1466 mutex_lock(&os05a20->mutex);
1467 /* Initialize try_fmt */
1468 try_fmt->width = def_mode->width;
1469 try_fmt->height = def_mode->height;
1470 try_fmt->code = def_mode->bus_fmt;
1471 try_fmt->field = V4L2_FIELD_NONE;
1472
1473 mutex_unlock(&os05a20->mutex);
1474 /* No crop or compose */
1475
1476 return 0;
1477 }
1478 #endif
1479
os05a20_enum_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_interval_enum * fie)1480 static int os05a20_enum_frame_interval(struct v4l2_subdev *sd,
1481 struct v4l2_subdev_pad_config *cfg,
1482 struct v4l2_subdev_frame_interval_enum *fie)
1483 {
1484 struct os05a20 *os05a20 = to_os05a20(sd);
1485
1486 if (fie->index >= os05a20->cfg_num)
1487 return -EINVAL;
1488
1489 fie->code = supported_modes[fie->index].bus_fmt;
1490 fie->width = supported_modes[fie->index].width;
1491 fie->height = supported_modes[fie->index].height;
1492 fie->interval = supported_modes[fie->index].max_fps;
1493 fie->reserved[0] = supported_modes[fie->index].hdr_mode;
1494 return 0;
1495 }
1496
1497 static const struct dev_pm_ops os05a20_pm_ops = {
1498 SET_RUNTIME_PM_OPS(os05a20_runtime_suspend,
1499 os05a20_runtime_resume, NULL)
1500 };
1501
1502 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1503 static const struct v4l2_subdev_internal_ops os05a20_internal_ops = {
1504 .open = os05a20_open,
1505 };
1506 #endif
1507
1508 static const struct v4l2_subdev_core_ops os05a20_core_ops = {
1509 .s_power = os05a20_s_power,
1510 .ioctl = os05a20_ioctl,
1511 #ifdef CONFIG_COMPAT
1512 .compat_ioctl32 = os05a20_compat_ioctl32,
1513 #endif
1514 };
1515
1516 static const struct v4l2_subdev_video_ops os05a20_video_ops = {
1517 .s_stream = os05a20_s_stream,
1518 .g_frame_interval = os05a20_g_frame_interval,
1519 };
1520
1521 static const struct v4l2_subdev_pad_ops os05a20_pad_ops = {
1522 .enum_mbus_code = os05a20_enum_mbus_code,
1523 .enum_frame_size = os05a20_enum_frame_sizes,
1524 .enum_frame_interval = os05a20_enum_frame_interval,
1525 .get_fmt = os05a20_get_fmt,
1526 .set_fmt = os05a20_set_fmt,
1527 .get_mbus_config = os05a20_g_mbus_config,
1528 };
1529
1530 static const struct v4l2_subdev_ops os05a20_subdev_ops = {
1531 .core = &os05a20_core_ops,
1532 .video = &os05a20_video_ops,
1533 .pad = &os05a20_pad_ops,
1534 };
1535
os05a20_set_ctrl(struct v4l2_ctrl * ctrl)1536 static int os05a20_set_ctrl(struct v4l2_ctrl *ctrl)
1537 {
1538 struct os05a20 *os05a20 = container_of(ctrl->handler,
1539 struct os05a20, ctrl_handler);
1540 struct i2c_client *client = os05a20->client;
1541 s64 max;
1542 int ret = 0;
1543 u32 again, dgain;
1544 u32 val = 0;
1545
1546 /* Propagate change of current control to all related controls */
1547 switch (ctrl->id) {
1548 case V4L2_CID_VBLANK:
1549 if (os05a20->cur_mode->hdr_mode == NO_HDR) {
1550 /* Update max exposure while meeting expected vblanking */
1551 max = os05a20->cur_mode->height + ctrl->val - 8;
1552 __v4l2_ctrl_modify_range(os05a20->exposure,
1553 os05a20->exposure->minimum, max,
1554 os05a20->exposure->step,
1555 os05a20->exposure->default_value);
1556 break;
1557 }
1558 }
1559
1560 if (!pm_runtime_get_if_in_use(&client->dev))
1561 return 0;
1562
1563 switch (ctrl->id) {
1564 case V4L2_CID_EXPOSURE:
1565 if (os05a20->cur_mode->hdr_mode != NO_HDR)
1566 goto ctrl_end;
1567 ret = os05a20_write_reg(os05a20->client,
1568 OS05A20_REG_EXP_LONG_H,
1569 OS05A20_REG_VALUE_16BIT,
1570 ctrl->val);
1571 dev_dbg(&client->dev, "set exposure 0x%x\n",
1572 ctrl->val);
1573 break;
1574 case V4L2_CID_ANALOGUE_GAIN:
1575 if (os05a20->cur_mode->hdr_mode != NO_HDR)
1576 goto ctrl_end;
1577 if (ctrl->val > 1984) {// >15.5x
1578 dgain = ctrl->val * 10 / 155;
1579 again = 1984;
1580 } else {
1581 dgain = 1024;
1582 again = ctrl->val;
1583 }
1584 ret = os05a20_write_reg(os05a20->client,
1585 OS05A20_REG_AGAIN_LONG_H,
1586 OS05A20_REG_VALUE_16BIT,
1587 again & 0x7ff);
1588 ret |= os05a20_write_reg(os05a20->client,
1589 OS05A20_REG_DGAIN_LONG_H,
1590 OS05A20_REG_VALUE_16BIT,
1591 dgain & 0x3fff);
1592 dev_dbg(&client->dev, "set analog gain 0x%x digital gain 0x%x\n",
1593 again, dgain);
1594 break;
1595 case V4L2_CID_VBLANK:
1596 ret = os05a20_write_reg(os05a20->client, OS05A20_REG_VTS,
1597 OS05A20_REG_VALUE_16BIT,
1598 ctrl->val + os05a20->cur_mode->height);
1599 dev_dbg(&client->dev, "set vblank 0x%x\n",
1600 ctrl->val);
1601 break;
1602 case V4L2_CID_TEST_PATTERN:
1603 ret = os05a20_enable_test_pattern(os05a20, ctrl->val);
1604 break;
1605 case V4L2_CID_HFLIP:
1606 ret = os05a20_read_reg(os05a20->client, OS05A20_MIRROR_REG,
1607 OS05A20_REG_VALUE_08BIT,
1608 &val);
1609 if (ctrl->val)
1610 val |= MIRROR_BIT_MASK;
1611 else
1612 val &= ~MIRROR_BIT_MASK;
1613 ret = os05a20_write_reg(os05a20->client, OS05A20_MIRROR_REG,
1614 OS05A20_REG_VALUE_08BIT,
1615 val);
1616 break;
1617 case V4L2_CID_VFLIP:
1618 ret = os05a20_read_reg(os05a20->client, OS05A20_FLIP_REG,
1619 OS05A20_REG_VALUE_08BIT,
1620 &val);
1621 if (ctrl->val)
1622 val |= FLIP_BIT_MASK;
1623 else
1624 val &= ~FLIP_BIT_MASK;
1625 ret = os05a20_write_reg(os05a20->client, OS05A20_FLIP_REG,
1626 OS05A20_REG_VALUE_08BIT,
1627 val);
1628 break;
1629 default:
1630 dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
1631 __func__, ctrl->id, ctrl->val);
1632 break;
1633 }
1634
1635 ctrl_end:
1636 pm_runtime_put(&client->dev);
1637
1638 return ret;
1639 }
1640
1641 static const struct v4l2_ctrl_ops os05a20_ctrl_ops = {
1642 .s_ctrl = os05a20_set_ctrl,
1643 };
1644
os05a20_initialize_controls(struct os05a20 * os05a20)1645 static int os05a20_initialize_controls(struct os05a20 *os05a20)
1646 {
1647 const struct os05a20_mode *mode;
1648 struct v4l2_ctrl_handler *handler;
1649 s64 exposure_max, vblank_def;
1650 u32 h_blank;
1651 int ret;
1652
1653 handler = &os05a20->ctrl_handler;
1654 mode = os05a20->cur_mode;
1655 ret = v4l2_ctrl_handler_init(handler, 9);
1656 if (ret)
1657 return ret;
1658 handler->lock = &os05a20->mutex;
1659
1660 os05a20->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
1661 V4L2_CID_LINK_FREQ,
1662 1, 0, link_freq_menu_items);
1663 /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
1664 os05a20->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
1665 V4L2_CID_PIXEL_RATE,
1666 0, PIXEL_RATE_WITH_750M,
1667 1, PIXEL_RATE_WITH_750M);
1668
1669 h_blank = mode->hts_def - mode->width;
1670 os05a20->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
1671 h_blank, h_blank, 1, h_blank);
1672 if (os05a20->hblank)
1673 os05a20->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1674
1675 vblank_def = mode->vts_def - mode->height;
1676 os05a20->vblank = v4l2_ctrl_new_std(handler, &os05a20_ctrl_ops,
1677 V4L2_CID_VBLANK, vblank_def,
1678 OS05A20_VTS_MAX - mode->height,
1679 1, vblank_def);
1680
1681 exposure_max = mode->vts_def - 8;
1682 os05a20->exposure = v4l2_ctrl_new_std(handler, &os05a20_ctrl_ops,
1683 V4L2_CID_EXPOSURE, OS05A20_EXPOSURE_MIN,
1684 exposure_max, OS05A20_EXPOSURE_STEP,
1685 mode->exp_def);
1686
1687 os05a20->anal_gain = v4l2_ctrl_new_std(handler, &os05a20_ctrl_ops,
1688 V4L2_CID_ANALOGUE_GAIN, OS05A20_GAIN_MIN,
1689 OS05A20_GAIN_MAX, OS05A20_GAIN_STEP,
1690 OS05A20_GAIN_DEFAULT);
1691
1692 os05a20->test_pattern =
1693 v4l2_ctrl_new_std_menu_items(handler,
1694 &os05a20_ctrl_ops, V4L2_CID_TEST_PATTERN,
1695 ARRAY_SIZE(os05a20_test_pattern_menu) - 1,
1696 0, 0, os05a20_test_pattern_menu);
1697
1698 os05a20->h_flip = v4l2_ctrl_new_std(handler, &os05a20_ctrl_ops,
1699 V4L2_CID_HFLIP, 0, 1, 1, 0);
1700
1701 os05a20->v_flip = v4l2_ctrl_new_std(handler, &os05a20_ctrl_ops,
1702 V4L2_CID_VFLIP, 0, 1, 1, 0);
1703 if (handler->error) {
1704 ret = handler->error;
1705 dev_err(&os05a20->client->dev,
1706 "Failed to init controls(%d)\n", ret);
1707 goto err_free_handler;
1708 }
1709
1710 os05a20->subdev.ctrl_handler = handler;
1711 os05a20->has_init_exp = false;
1712
1713 return 0;
1714
1715 err_free_handler:
1716 v4l2_ctrl_handler_free(handler);
1717
1718 return ret;
1719 }
1720
os05a20_check_sensor_id(struct os05a20 * os05a20,struct i2c_client * client)1721 static int os05a20_check_sensor_id(struct os05a20 *os05a20,
1722 struct i2c_client *client)
1723 {
1724 struct device *dev = &os05a20->client->dev;
1725 u32 id = 0;
1726 int ret;
1727
1728 if (os05a20->is_thunderboot) {
1729 dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
1730 return 0;
1731 }
1732
1733 ret = os05a20_read_reg(client, OS05A20_REG_CHIP_ID,
1734 OS05A20_REG_VALUE_24BIT, &id);
1735 if (id != CHIP_ID) {
1736 dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
1737 return -ENODEV;
1738 }
1739
1740 dev_info(dev, "Detected OV%06x sensor\n", CHIP_ID);
1741
1742 return 0;
1743 }
1744
os05a20_configure_regulators(struct os05a20 * os05a20)1745 static int os05a20_configure_regulators(struct os05a20 *os05a20)
1746 {
1747 unsigned int i;
1748
1749 for (i = 0; i < OS05A20_NUM_SUPPLIES; i++)
1750 os05a20->supplies[i].supply = os05a20_supply_names[i];
1751
1752 return devm_regulator_bulk_get(&os05a20->client->dev,
1753 OS05A20_NUM_SUPPLIES,
1754 os05a20->supplies);
1755 }
1756
os05a20_probe(struct i2c_client * client,const struct i2c_device_id * id)1757 static int os05a20_probe(struct i2c_client *client,
1758 const struct i2c_device_id *id)
1759 {
1760 struct device *dev = &client->dev;
1761 struct device_node *node = dev->of_node;
1762 struct os05a20 *os05a20;
1763 struct v4l2_subdev *sd;
1764 char facing[2];
1765 int ret;
1766 u32 i, hdr_mode = 0;
1767
1768 dev_info(dev, "driver version: %02x.%02x.%02x",
1769 DRIVER_VERSION >> 16,
1770 (DRIVER_VERSION & 0xff00) >> 8,
1771 DRIVER_VERSION & 0x00ff);
1772
1773 os05a20 = devm_kzalloc(dev, sizeof(*os05a20), GFP_KERNEL);
1774 if (!os05a20)
1775 return -ENOMEM;
1776
1777 ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
1778 &os05a20->module_index);
1779 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
1780 &os05a20->module_facing);
1781 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
1782 &os05a20->module_name);
1783 ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
1784 &os05a20->len_name);
1785 if (ret) {
1786 dev_err(dev, "could not get module information!\n");
1787 return -EINVAL;
1788 }
1789
1790 os05a20->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
1791 ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE,
1792 &hdr_mode);
1793 if (ret) {
1794 hdr_mode = NO_HDR;
1795 dev_warn(dev, " Get hdr mode failed! no hdr default\n");
1796 }
1797 os05a20->cfg_num = ARRAY_SIZE(supported_modes);
1798 for (i = 0; i < os05a20->cfg_num; i++) {
1799 if (hdr_mode == supported_modes[i].hdr_mode) {
1800 os05a20->cur_mode = &supported_modes[i];
1801 break;
1802 }
1803 }
1804 os05a20->client = client;
1805
1806 os05a20->xvclk = devm_clk_get(dev, "xvclk");
1807 if (IS_ERR(os05a20->xvclk)) {
1808 dev_err(dev, "Failed to get xvclk\n");
1809 return -EINVAL;
1810 }
1811
1812 os05a20->power_gpio = devm_gpiod_get(dev, "power", GPIOD_ASIS);
1813 if (IS_ERR(os05a20->power_gpio))
1814 dev_warn(dev, "Failed to get power-gpios\n");
1815
1816 os05a20->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
1817 if (IS_ERR(os05a20->reset_gpio))
1818 dev_warn(dev, "Failed to get reset-gpios\n");
1819
1820 os05a20->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
1821 if (IS_ERR(os05a20->pwdn_gpio))
1822 dev_warn(dev, "Failed to get pwdn-gpios\n");
1823
1824 os05a20->pinctrl = devm_pinctrl_get(dev);
1825 if (!IS_ERR(os05a20->pinctrl)) {
1826 os05a20->pins_default =
1827 pinctrl_lookup_state(os05a20->pinctrl,
1828 OF_CAMERA_PINCTRL_STATE_DEFAULT);
1829 if (IS_ERR(os05a20->pins_default))
1830 dev_err(dev, "could not get default pinstate\n");
1831
1832 os05a20->pins_sleep =
1833 pinctrl_lookup_state(os05a20->pinctrl,
1834 OF_CAMERA_PINCTRL_STATE_SLEEP);
1835 if (IS_ERR(os05a20->pins_sleep))
1836 dev_err(dev, "could not get sleep pinstate\n");
1837 } else {
1838 dev_err(dev, "no pinctrl\n");
1839 }
1840
1841 ret = os05a20_configure_regulators(os05a20);
1842 if (ret) {
1843 dev_err(dev, "Failed to get power regulators\n");
1844 return ret;
1845 }
1846
1847 mutex_init(&os05a20->mutex);
1848
1849 sd = &os05a20->subdev;
1850 v4l2_i2c_subdev_init(sd, client, &os05a20_subdev_ops);
1851 ret = os05a20_initialize_controls(os05a20);
1852 if (ret)
1853 goto err_destroy_mutex;
1854
1855 ret = __os05a20_power_on(os05a20);
1856 if (ret)
1857 goto err_free_handler;
1858
1859 ret = os05a20_check_sensor_id(os05a20, client);
1860 if (ret)
1861 goto err_power_off;
1862
1863 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1864 sd->internal_ops = &os05a20_internal_ops;
1865 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1866 #endif
1867 #if defined(CONFIG_MEDIA_CONTROLLER)
1868 os05a20->pad.flags = MEDIA_PAD_FL_SOURCE;
1869 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1870 ret = media_entity_pads_init(&sd->entity, 1, &os05a20->pad);
1871 if (ret < 0)
1872 goto err_power_off;
1873 #endif
1874
1875 memset(facing, 0, sizeof(facing));
1876 if (strcmp(os05a20->module_facing, "back") == 0)
1877 facing[0] = 'b';
1878 else
1879 facing[0] = 'f';
1880
1881 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
1882 os05a20->module_index, facing,
1883 OS05A20_NAME, dev_name(sd->dev));
1884 ret = v4l2_async_register_subdev_sensor_common(sd);
1885 if (ret) {
1886 dev_err(dev, "v4l2 async register subdev failed\n");
1887 goto err_clean_entity;
1888 }
1889
1890 pm_runtime_set_active(dev);
1891 pm_runtime_enable(dev);
1892 pm_runtime_idle(dev);
1893 return 0;
1894
1895 err_clean_entity:
1896 #if defined(CONFIG_MEDIA_CONTROLLER)
1897 media_entity_cleanup(&sd->entity);
1898 #endif
1899 err_power_off:
1900 __os05a20_power_off(os05a20);
1901 err_free_handler:
1902 v4l2_ctrl_handler_free(&os05a20->ctrl_handler);
1903 err_destroy_mutex:
1904 mutex_destroy(&os05a20->mutex);
1905
1906 return ret;
1907 }
1908
os05a20_remove(struct i2c_client * client)1909 static int os05a20_remove(struct i2c_client *client)
1910 {
1911 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1912 struct os05a20 *os05a20 = to_os05a20(sd);
1913
1914 v4l2_async_unregister_subdev(sd);
1915 #if defined(CONFIG_MEDIA_CONTROLLER)
1916 media_entity_cleanup(&sd->entity);
1917 #endif
1918 v4l2_ctrl_handler_free(&os05a20->ctrl_handler);
1919 mutex_destroy(&os05a20->mutex);
1920
1921 pm_runtime_disable(&client->dev);
1922 if (!pm_runtime_status_suspended(&client->dev))
1923 __os05a20_power_off(os05a20);
1924 pm_runtime_set_suspended(&client->dev);
1925
1926 return 0;
1927 }
1928
1929 #if IS_ENABLED(CONFIG_OF)
1930 static const struct of_device_id os05a20_of_match[] = {
1931 { .compatible = "ovti,os05a20" },
1932 {},
1933 };
1934 MODULE_DEVICE_TABLE(of, os05a20_of_match);
1935 #endif
1936
1937 static const struct i2c_device_id os05a20_match_id[] = {
1938 { "ovti,os05a20", 0 },
1939 { },
1940 };
1941
1942 static struct i2c_driver os05a20_i2c_driver = {
1943 .driver = {
1944 .name = OS05A20_NAME,
1945 .pm = &os05a20_pm_ops,
1946 .of_match_table = of_match_ptr(os05a20_of_match),
1947 },
1948 .probe = &os05a20_probe,
1949 .remove = &os05a20_remove,
1950 .id_table = os05a20_match_id,
1951 };
1952
1953 #ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
1954 module_i2c_driver(os05a20_i2c_driver);
1955 #else
sensor_mod_init(void)1956 static int __init sensor_mod_init(void)
1957 {
1958 return i2c_add_driver(&os05a20_i2c_driver);
1959 }
1960
sensor_mod_exit(void)1961 static void __exit sensor_mod_exit(void)
1962 {
1963 i2c_del_driver(&os05a20_i2c_driver);
1964 }
1965
1966 device_initcall_sync(sensor_mod_init);
1967 module_exit(sensor_mod_exit);
1968 #endif
1969
1970 MODULE_DESCRIPTION("OmniVision os05a20 sensor driver");
1971 MODULE_LICENSE("GPL v2");
1972