1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * sc230ai driver
4 *
5 * Copyright (C) 2022 Rockchip Electronics Co., Ltd.
6 *
7 */
8 //#define DEBUG
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 <linux/rk-preisp.h>
23 #include <media/media-entity.h>
24 #include <media/v4l2-async.h>
25 #include <media/v4l2-ctrls.h>
26 #include <media/v4l2-subdev.h>
27 #include <linux/pinctrl/consumer.h>
28 #include "../platform/rockchip/isp/rkisp_tb_helper.h"
29
30 #define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x00)
31
32 #ifndef V4L2_CID_DIGITAL_GAIN
33 #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
34 #endif
35
36 #define SC230AI_LANES 2
37 #define SC230AI_BITS_PER_SAMPLE 10
38 #define SC230AI_LINK_FREQ_185 92812500// 185.625Mbps
39 #define SC230AI_LINK_FREQ_371 185625000// 371.25Mbps
40
41 #define PIXEL_RATE_WITH_185M_10BIT (SC230AI_LINK_FREQ_185 * 2 * \
42 SC230AI_LANES / SC230AI_BITS_PER_SAMPLE)
43
44 #define PIXEL_RATE_WITH_371M_10BIT (SC230AI_LINK_FREQ_371 * 2 * \
45 SC230AI_LANES / SC230AI_BITS_PER_SAMPLE)
46
47 #define SC230AI_XVCLK_FREQ 27000000
48
49 #define CHIP_ID 0xcb34
50 #define SC230AI_REG_CHIP_ID 0x3107
51
52 #define SC230AI_REG_CTRL_MODE 0x0100
53 #define SC230AI_MODE_SW_STANDBY 0x0
54 #define SC230AI_MODE_STREAMING BIT(0)
55
56 #define SC230AI_REG_EXPOSURE_H 0x3e00
57 #define SC230AI_REG_EXPOSURE_M 0x3e01
58 #define SC230AI_REG_EXPOSURE_L 0x3e02
59 #define SC230AI_REG_SEXPOSURE_H 0x3e22
60 #define SC230AI_REG_SEXPOSURE_M 0x3e04
61 #define SC230AI_REG_SEXPOSURE_L 0x3e05
62 #define SC230AI_EXPOSURE_MIN 1
63 #define SC230AI_EXPOSURE_STEP 1
64 #define SC230AI_EXPOSURE_LIN_MAX (2 * 0x465 - 9)
65 #define SC230AI_EXPOSURE_HDR_MAX_S (2 * 0x465 - 9)
66 #define SC230AI_EXPOSURE_HDR_MAX_L (2 * 0x465 - 9)
67 #define SC230AI_VTS_MAX 0x7fff
68
69 #define SC230AI_REG_DIG_GAIN 0x3e06
70 #define SC230AI_REG_DIG_FINE_GAIN 0x3e07
71 #define SC230AI_REG_ANA_GAIN 0x3e09
72 #define SC230AI_REG_SDIG_GAIN 0x3e10
73 #define SC230AI_REG_SDIG_FINE_GAIN 0x3e11
74 #define SC230AI_REG_SANA_GAIN 0x3e12
75 #define SC230AI_REG_SANA_FINE_GAIN 0x3e13
76 #define SC230AI_GAIN_MIN 1000
77 #define SC230AI_GAIN_MAX 1722628 //108.512*15.875*1000
78 #define SC230AI_GAIN_STEP 1
79 #define SC230AI_GAIN_DEFAULT 1000
80 #define SC230AI_LGAIN 0
81 #define SC230AI_SGAIN 1
82
83 #define SC230AI_REG_GROUP_HOLD 0x3812
84 #define SC230AI_GROUP_HOLD_START 0x00
85 #define SC230AI_GROUP_HOLD_END 0x30
86
87 #define SC230AI_REG_HIGH_TEMP_H 0x3974
88 #define SC230AI_REG_HIGH_TEMP_L 0x3975
89
90 #define SC230AI_REG_TEST_PATTERN 0x4501
91 #define SC230AI_TEST_PATTERN_BIT_MASK BIT(3)
92
93 #define SC230AI_REG_VTS_H 0x320e
94 #define SC230AI_REG_VTS_L 0x320f
95
96 #define SC230AI_FLIP_MIRROR_REG 0x3221
97
98 #define SC230AI_FETCH_EXP_H(VAL) (((VAL) >> 12) & 0xF)
99 #define SC230AI_FETCH_EXP_M(VAL) (((VAL) >> 4) & 0xFF)
100 #define SC230AI_FETCH_EXP_L(VAL) (((VAL) & 0xF) << 4)
101
102 #define SC230AI_FETCH_AGAIN_H(VAL) (((VAL) >> 8) & 0x03)
103 #define SC230AI_FETCH_AGAIN_L(VAL) ((VAL) & 0xFF)
104
105 #define SC230AI_FETCH_MIRROR(VAL, ENABLE) (ENABLE ? VAL | 0x06 : VAL & 0xf9)
106 #define SC230AI_FETCH_FLIP(VAL, ENABLE) (ENABLE ? VAL | 0x60 : VAL & 0x9f)
107
108 #define REG_DELAY 0xFFFE
109 #define REG_NULL 0xFFFF
110
111 #define SC230AI_REG_VALUE_08BIT 1
112 #define SC230AI_REG_VALUE_16BIT 2
113 #define SC230AI_REG_VALUE_24BIT 3
114
115 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
116 #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
117 #define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
118 #define SC230AI_NAME "sc230ai"
119
120 static const char * const sc230ai_supply_names[] = {
121 "avdd", /* Analog power */
122 "dovdd", /* Digital I/O power */
123 "dvdd", /* Digital core power */
124 };
125
126 #define SC230AI_NUM_SUPPLIES ARRAY_SIZE(sc230ai_supply_names)
127
128 struct regval {
129 u16 addr;
130 u8 val;
131 };
132
133 struct sc230ai_mode {
134 u32 bus_fmt;
135 u32 width;
136 u32 height;
137 struct v4l2_fract max_fps;
138 u32 hts_def;
139 u32 vts_def;
140 u32 exp_def;
141 u32 mipi_freq_idx;
142 u32 bpp;
143 const struct regval *reg_list;
144 u32 hdr_mode;
145 u32 vc[PAD_MAX];
146 };
147
148 struct sc230ai {
149 struct i2c_client *client;
150 struct clk *xvclk;
151 struct gpio_desc *reset_gpio;
152 struct gpio_desc *pwdn_gpio;
153 struct regulator_bulk_data supplies[SC230AI_NUM_SUPPLIES];
154
155 struct pinctrl *pinctrl;
156 struct pinctrl_state *pins_default;
157 struct pinctrl_state *pins_sleep;
158
159 struct v4l2_subdev subdev;
160 struct media_pad pad;
161 struct v4l2_ctrl_handler ctrl_handler;
162 struct v4l2_ctrl *exposure;
163 struct v4l2_ctrl *anal_gain;
164 struct v4l2_ctrl *digi_gain;
165 struct v4l2_ctrl *hblank;
166 struct v4l2_ctrl *vblank;
167 struct v4l2_ctrl *pixel_rate;
168 struct v4l2_ctrl *link_freq;
169 struct v4l2_ctrl *test_pattern;
170 struct mutex mutex;
171 struct v4l2_fract cur_fps;
172 bool streaming;
173 bool power_on;
174 const struct sc230ai_mode *cur_mode;
175 u32 module_index;
176 const char *module_facing;
177 const char *module_name;
178 const char *len_name;
179 u32 cur_vts;
180 bool has_init_exp;
181 bool is_thunderboot;
182 bool is_first_streamoff;
183 struct preisp_hdrae_exp_s init_hdrae_exp;
184 };
185
186 #define to_sc230ai(sd) container_of(sd, struct sc230ai, subdev)
187
188 /*
189 * Xclk 27Mhz
190 */
191 static const struct regval sc230ai_global_regs[] = {
192 {REG_NULL, 0x00},
193 };
194
195 static const struct regval sc230ai_linear_10_640x480_regs[] = {
196 {0x0103, 0x01},
197 {0x0100, 0x00},
198 {0x36e9, 0x80},
199 {0x37f9, 0x80},
200 {0x301f, 0x2d},
201 {0x3200, 0x00},
202 {0x3201, 0x00},
203 {0x3202, 0x00},
204 {0x3203, 0x3c},
205 {0x3204, 0x07},
206 {0x3205, 0x87},
207 {0x3206, 0x04},
208 {0x3207, 0x03},
209 {0x3208, 0x02},
210 {0x3209, 0x80},
211 {0x320a, 0x01},
212 {0x320b, 0xe0},
213 {0x320e, 0x02},
214 {0x320f, 0x32},
215 {0x3210, 0x00},
216 {0x3211, 0xa2},
217 {0x3212, 0x00},
218 {0x3213, 0x02},
219 {0x3215, 0x31},
220 {0x3220, 0x01},
221 {0x3301, 0x09},
222 {0x3304, 0x50},
223 {0x3306, 0x48},
224 {0x3308, 0x18},
225 {0x3309, 0x68},
226 {0x330a, 0x00},
227 {0x330b, 0xc0},
228 {0x331e, 0x41},
229 {0x331f, 0x59},
230 {0x3333, 0x10},
231 {0x3334, 0x40},
232 {0x335d, 0x60},
233 {0x335e, 0x06},
234 {0x335f, 0x08},
235 {0x3364, 0x5e},
236 {0x337c, 0x02},
237 {0x337d, 0x0a},
238 {0x3390, 0x01},
239 {0x3391, 0x0b},
240 {0x3392, 0x0f},
241 {0x3393, 0x0c},
242 {0x3394, 0x0d},
243 {0x3395, 0x60},
244 {0x3396, 0x48},
245 {0x3397, 0x49},
246 {0x3398, 0x4f},
247 {0x3399, 0x0a},
248 {0x339a, 0x0f},
249 {0x339b, 0x14},
250 {0x339c, 0x60},
251 {0x33a2, 0x04},
252 {0x33af, 0x40},
253 {0x33b1, 0x80},
254 {0x33b3, 0x40},
255 {0x33b9, 0x0a},
256 {0x33f9, 0x70},
257 {0x33fb, 0x90},
258 {0x33fc, 0x4b},
259 {0x33fd, 0x5f},
260 {0x349f, 0x03},
261 {0x34a6, 0x4b},
262 {0x34a7, 0x4f},
263 {0x34a8, 0x30},
264 {0x34a9, 0x20},
265 {0x34aa, 0x00},
266 {0x34ab, 0xe0},
267 {0x34ac, 0x01},
268 {0x34ad, 0x00},
269 {0x34f8, 0x5f},
270 {0x34f9, 0x10},
271 {0x3630, 0xc0},
272 {0x3633, 0x44},
273 {0x3637, 0x29},
274 {0x363b, 0x20},
275 {0x3670, 0x09},
276 {0x3674, 0xb0},
277 {0x3675, 0x80},
278 {0x3676, 0x88},
279 {0x367c, 0x40},
280 {0x367d, 0x49},
281 {0x3690, 0x44},
282 {0x3691, 0x44},
283 {0x3692, 0x54},
284 {0x369c, 0x49},
285 {0x369d, 0x4f},
286 {0x36ae, 0x4b},
287 {0x36af, 0x4f},
288 {0x36b0, 0x87},
289 {0x36b1, 0x9b},
290 {0x36b2, 0xb7},
291 {0x36d0, 0x01},
292 {0x36ea, 0x0b},
293 {0x36eb, 0x04},
294 {0x36ec, 0x1c},
295 {0x36ed, 0x24},
296 {0x370f, 0x01},
297 {0x3722, 0x17},
298 {0x3728, 0x90},
299 {0x37b0, 0x17},
300 {0x37b1, 0x17},
301 {0x37b2, 0x97},
302 {0x37b3, 0x4b},
303 {0x37b4, 0x4f},
304 {0x37fa, 0x0b},
305 {0x37fb, 0x24},
306 {0x37fc, 0x10},
307 {0x37fd, 0x22},
308 {0x3901, 0x02},
309 {0x3902, 0xc5},
310 {0x3904, 0x04},
311 {0x3907, 0x00},
312 {0x3908, 0x41},
313 {0x3909, 0x00},
314 {0x390a, 0x00},
315 {0x391f, 0x04},
316 {0x3933, 0x84},
317 {0x3934, 0x02},
318 {0x3940, 0x62},
319 {0x3941, 0x00},
320 {0x3942, 0x04},
321 {0x3943, 0x03},
322 {0x3e00, 0x00},
323 {0x3e01, 0x45},
324 {0x3e02, 0xb0},
325 {0x440e, 0x02},
326 {0x450d, 0x11},
327 {0x4819, 0x05},
328 {0x481b, 0x03},
329 {0x481d, 0x0a},
330 {0x481f, 0x02},
331 {0x4821, 0x08},
332 {0x4823, 0x03},
333 {0x4825, 0x02},
334 {0x4827, 0x03},
335 {0x4829, 0x04},
336 {0x5000, 0x46},
337 {0x5010, 0x01},
338 {0x5787, 0x08},
339 {0x5788, 0x03},
340 {0x5789, 0x00},
341 {0x578a, 0x10},
342 {0x578b, 0x08},
343 {0x578c, 0x00},
344 {0x5790, 0x08},
345 {0x5791, 0x04},
346 {0x5792, 0x00},
347 {0x5793, 0x10},
348 {0x5794, 0x08},
349 {0x5795, 0x00},
350 {0x5799, 0x06},
351 {0x57ad, 0x00},
352 {0x5900, 0xf1},
353 {0x5901, 0x04},
354 {0x5ae0, 0xfe},
355 {0x5ae1, 0x40},
356 {0x5ae2, 0x3f},
357 {0x5ae3, 0x38},
358 {0x5ae4, 0x28},
359 {0x5ae5, 0x3f},
360 {0x5ae6, 0x38},
361 {0x5ae7, 0x28},
362 {0x5ae8, 0x3f},
363 {0x5ae9, 0x3c},
364 {0x5aea, 0x2c},
365 {0x5aeb, 0x3f},
366 {0x5aec, 0x3c},
367 {0x5aed, 0x2c},
368 {0x5af4, 0x3f},
369 {0x5af5, 0x38},
370 {0x5af6, 0x28},
371 {0x5af7, 0x3f},
372 {0x5af8, 0x38},
373 {0x5af9, 0x28},
374 {0x5afa, 0x3f},
375 {0x5afb, 0x3c},
376 {0x5afc, 0x2c},
377 {0x5afd, 0x3f},
378 {0x5afe, 0x3c},
379 {0x5aff, 0x2c},
380 {0x36e9, 0x20},
381 {0x37f9, 0x24},
382 {REG_NULL, 0x00},
383 };
384
385 /*
386 * Xclk 27Mhz
387 * max_framerate 25fps
388 * mipi_datarate per lane 371.25Mbps, 2lane
389 */
390 static const struct regval sc230ai_linear_10_1920x1080_regs[] = {
391 {0x0103, 0x01},
392 {0x0100, 0x00},
393 {0x36e9, 0x80},
394 {0x37f9, 0x80},
395 {0x301f, 0x01},
396 {0x320e, 0x05},
397 {0x320f, 0x46},
398 {0x3301, 0x07},
399 {0x3304, 0x50},
400 {0x3306, 0x70},
401 {0x3308, 0x18},
402 {0x3309, 0x68},
403 {0x330a, 0x01},
404 {0x330b, 0x20},
405 {0x3314, 0x15},
406 {0x331e, 0x41},
407 {0x331f, 0x59},
408 {0x3333, 0x10},
409 {0x3334, 0x40},
410 {0x335d, 0x60},
411 {0x335e, 0x06},
412 {0x335f, 0x08},
413 {0x3364, 0x5e},
414 {0x337c, 0x02},
415 {0x337d, 0x0a},
416 {0x3390, 0x01},
417 {0x3391, 0x0b},
418 {0x3392, 0x0f},
419 {0x3393, 0x09},
420 {0x3394, 0x0d},
421 {0x3395, 0x60},
422 {0x3396, 0x48},
423 {0x3397, 0x49},
424 {0x3398, 0x4b},
425 {0x3399, 0x06},
426 {0x339a, 0x0a},
427 {0x339b, 0x0d},
428 {0x339c, 0x60},
429 {0x33a2, 0x04},
430 {0x33ad, 0x2c},
431 {0x33af, 0x40},
432 {0x33b1, 0x80},
433 {0x33b3, 0x40},
434 {0x33b9, 0x0a},
435 {0x33f9, 0x78},
436 {0x33fb, 0xa0},
437 {0x33fc, 0x4f},
438 {0x33fd, 0x5f},
439 {0x349f, 0x03},
440 {0x34a6, 0x4b},
441 {0x34a7, 0x5f},
442 {0x34a8, 0x30},
443 {0x34a9, 0x20},
444 {0x34aa, 0x01},
445 {0x34ab, 0x28},
446 {0x34ac, 0x01},
447 {0x34ad, 0x58},
448 {0x34f8, 0x7f},
449 {0x34f9, 0x10},
450 {0x3630, 0xc0},
451 {0x3632, 0x54},
452 {0x3633, 0x44},
453 {0x363b, 0x20},
454 {0x363c, 0x08},
455 {0x3670, 0x09},
456 {0x3674, 0xb0},
457 {0x3675, 0x80},
458 {0x3676, 0x88},
459 {0x367c, 0x40},
460 {0x367d, 0x49},
461 {0x3690, 0x33},
462 {0x3691, 0x33},
463 {0x3692, 0x43},
464 {0x369c, 0x49},
465 {0x369d, 0x4f},
466 {0x36ae, 0x4b},
467 {0x36af, 0x4f},
468 {0x36b0, 0x87},
469 {0x36b1, 0x9b},
470 {0x36b2, 0xb7},
471 {0x36d0, 0x01},
472 {0x3722, 0x97},
473 {0x3724, 0x22},
474 {0x3728, 0x90},
475 {0x3901, 0x02},
476 {0x3902, 0xc5},
477 {0x3904, 0x04},
478 {0x3907, 0x00},
479 {0x3908, 0x41},
480 {0x3909, 0x00},
481 {0x390a, 0x00},
482 {0x3933, 0x84},
483 {0x3934, 0x0a},
484 {0x3940, 0x64},
485 {0x3941, 0x00},
486 {0x3942, 0x04},
487 {0x3943, 0x0b},
488 {0x3e00, 0x00},
489 {0x3e01, 0x8c},
490 {0x3e02, 0x10},
491 {0x440e, 0x02},
492 {0x450d, 0x11},
493 {0x5010, 0x01},
494 {0x5787, 0x08},
495 {0x5788, 0x03},
496 {0x5789, 0x00},
497 {0x578a, 0x10},
498 {0x578b, 0x08},
499 {0x578c, 0x00},
500 {0x5790, 0x08},
501 {0x5791, 0x04},
502 {0x5792, 0x00},
503 {0x5793, 0x10},
504 {0x5794, 0x08},
505 {0x5795, 0x00},
506 {0x5799, 0x06},
507 {0x57ad, 0x00},
508 {0x5ae0, 0xfe},
509 {0x5ae1, 0x40},
510 {0x5ae2, 0x3f},
511 {0x5ae3, 0x38},
512 {0x5ae4, 0x28},
513 {0x5ae5, 0x3f},
514 {0x5ae6, 0x38},
515 {0x5ae7, 0x28},
516 {0x5ae8, 0x3f},
517 {0x5ae9, 0x3c},
518 {0x5aea, 0x2c},
519 {0x5aeb, 0x3f},
520 {0x5aec, 0x3c},
521 {0x5aed, 0x2c},
522 {0x5af4, 0x3f},
523 {0x5af5, 0x38},
524 {0x5af6, 0x28},
525 {0x5af7, 0x3f},
526 {0x5af8, 0x38},
527 {0x5af9, 0x28},
528 {0x5afa, 0x3f},
529 {0x5afb, 0x3c},
530 {0x5afc, 0x2c},
531 {0x5afd, 0x3f},
532 {0x5afe, 0x3c},
533 {0x5aff, 0x2c},
534 {0x36e9, 0x20},
535 {0x37f9, 0x27},
536 //{0x0100, 0x01},
537 {REG_NULL, 0x00},
538 };
539
540
541 static const struct sc230ai_mode supported_modes[] = {
542 {
543 .width = 1920,
544 .height = 1080,
545 .max_fps = {
546 .numerator = 10000,
547 .denominator = 250000,
548 },
549 .exp_def = 0x0460,
550 .hts_def = 0x44C * 2,
551 .vts_def = 0x0546,
552 .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
553 .reg_list = sc230ai_linear_10_1920x1080_regs,
554 .hdr_mode = NO_HDR,
555 .bpp = 10,
556 .mipi_freq_idx = 1,
557 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
558 }, {
559 .width = 640,
560 .height = 480,
561 .max_fps = {
562 .numerator = 10000,
563 .denominator = 1200000,
564 },
565 .exp_def = 0x0232 - 9,
566 .hts_def = 0x96 * 8,
567 .vts_def = 0x0232,
568 .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
569 .reg_list = sc230ai_linear_10_640x480_regs,
570 .hdr_mode = NO_HDR,
571 .bpp = 10,
572 .mipi_freq_idx = 1,
573 .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
574 },
575 };
576
577 static const s64 link_freq_menu_items[] = {
578 SC230AI_LINK_FREQ_185,
579 SC230AI_LINK_FREQ_371
580 };
581
582 static const char * const sc230ai_test_pattern_menu[] = {
583 "Disabled",
584 "Vertical Color Bar Type 1",
585 "Vertical Color Bar Type 2",
586 "Vertical Color Bar Type 3",
587 "Vertical Color Bar Type 4"
588 };
589
590 /* Write registers up to 4 at a time */
sc230ai_write_reg(struct i2c_client * client,u16 reg,u32 len,u32 val)591 static int sc230ai_write_reg(struct i2c_client *client, u16 reg,
592 u32 len, u32 val)
593 {
594 u32 buf_i, val_i;
595 u8 buf[6];
596 u8 *val_p;
597 __be32 val_be;
598
599 if (len > 4)
600 return -EINVAL;
601
602 buf[0] = reg >> 8;
603 buf[1] = reg & 0xff;
604
605 val_be = cpu_to_be32(val);
606 val_p = (u8 *)&val_be;
607 buf_i = 2;
608 val_i = 4 - len;
609
610 while (val_i < 4)
611 buf[buf_i++] = val_p[val_i++];
612
613 if (i2c_master_send(client, buf, len + 2) != len + 2)
614 return -EIO;
615
616 return 0;
617 }
618
sc230ai_write_array(struct i2c_client * client,const struct regval * regs)619 static int sc230ai_write_array(struct i2c_client *client,
620 const struct regval *regs)
621 {
622 u32 i;
623 int ret = 0;
624
625 for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++)
626 ret = sc230ai_write_reg(client, regs[i].addr,
627 SC230AI_REG_VALUE_08BIT, regs[i].val);
628
629 return ret;
630 }
631
632 /* Read registers up to 4 at a time */
sc230ai_read_reg(struct i2c_client * client,u16 reg,unsigned int len,u32 * val)633 static int sc230ai_read_reg(struct i2c_client *client, u16 reg, unsigned int len,
634 u32 *val)
635 {
636 struct i2c_msg msgs[2];
637 u8 *data_be_p;
638 __be32 data_be = 0;
639 __be16 reg_addr_be = cpu_to_be16(reg);
640 int ret;
641
642 if (len > 4 || !len)
643 return -EINVAL;
644
645 data_be_p = (u8 *)&data_be;
646 /* Write register address */
647 msgs[0].addr = client->addr;
648 msgs[0].flags = 0;
649 msgs[0].len = 2;
650 msgs[0].buf = (u8 *)®_addr_be;
651
652 /* Read data from register */
653 msgs[1].addr = client->addr;
654 msgs[1].flags = I2C_M_RD;
655 msgs[1].len = len;
656 msgs[1].buf = &data_be_p[4 - len];
657
658 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
659 if (ret != ARRAY_SIZE(msgs))
660 return -EIO;
661
662 *val = be32_to_cpu(data_be);
663
664 return 0;
665 }
666
sc230ai_get_gain_reg(struct sc230ai * sc230ai,u32 * again,u32 * dgain,u32 * dgain_fine,u32 total_gain)667 static int sc230ai_get_gain_reg(struct sc230ai *sc230ai, u32 *again, u32 *dgain,
668 u32 *dgain_fine, u32 total_gain)
669 {
670 int ret = 0;
671
672 if (total_gain < SC230AI_GAIN_MIN)
673 total_gain = SC230AI_GAIN_MIN;
674 else if (total_gain > SC230AI_GAIN_MAX)
675 total_gain = SC230AI_GAIN_MAX;
676
677 if (total_gain < 2000) { /* 1 ~ 2 gain*/
678 *again = 0x00;
679 *dgain = 0x00;
680 *dgain_fine = total_gain * 128 / 1000;
681 } else if (total_gain < 3391) { /* 2 ~ 3.391 gain*/
682 *again = 0x01;
683 *dgain = 0x00;
684 *dgain_fine = total_gain * 128 / 1000 / 2;
685 } else if (total_gain < 3391 * 2) { /* 3.391 ~ 6.782 gain*/
686 *again = 0x40;
687 *dgain = 0x00;
688 *dgain_fine = total_gain * 128 / 3391;
689 } else if (total_gain < 3391 * 4) { /* 6.782 ~ 13.564 gain*/
690 *again = 0x48;
691 *dgain = 0x00;
692 *dgain_fine = total_gain * 128 / 3391 / 2;
693 } else if (total_gain < 3391 * 8) { /* 13.564 ~ 27.128 gain*/
694 *again = 0x49;
695 *dgain = 0x00;
696 *dgain_fine = total_gain * 128 / 3391 / 4;
697 } else if (total_gain < 3391 * 16) { /* 27.128 ~ 54.256 gain*/
698 *again = 0x4b;
699 *dgain = 0x00;
700 *dgain_fine = total_gain * 128 / 3391 / 8;
701 } else if (total_gain < 3391 * 32) { /* 54.256 ~ 108.512 gain*/
702 *again = 0x4f;
703 *dgain = 0x00;
704 *dgain_fine = total_gain * 128 / 3391 / 16;
705 } else if (total_gain < 3391 * 64) { /* 108.512 ~ 217.024 gain*/
706 *again = 0x5f;
707 *dgain = 0x00;
708 *dgain_fine = total_gain * 128 / 3391 / 32;
709 } else if (total_gain < 3391 * 128) { /* 217.024 ~ 434.048 gain*/
710 *again = 0x5f;
711 *dgain = 0x01;
712 *dgain_fine = total_gain * 128 / 3391 / 64;
713 } else if (total_gain < 3391 * 256) { /* 434.048 ~ 868.096 gain*/
714 *again = 0x5f;
715 *dgain = 0x03;
716 *dgain_fine = total_gain * 128 / 3391 / 128;
717 } else if (total_gain < 3391 * 512) { /* 868.096 ~ 1736.192 gain*/
718 *again = 0x5f;
719 *dgain = 0x07;
720 *dgain_fine = total_gain * 128 / 3391 / 128;
721 }
722
723 return ret;
724 }
725
sc230ai_set_hdrae(struct sc230ai * sc230ai,struct preisp_hdrae_exp_s * ae)726 static int sc230ai_set_hdrae(struct sc230ai *sc230ai,
727 struct preisp_hdrae_exp_s *ae)
728 {
729 int ret = 0;
730
731 return ret;
732 }
733
sc230ai_get_reso_dist(const struct sc230ai_mode * mode,struct v4l2_mbus_framefmt * framefmt)734 static int sc230ai_get_reso_dist(const struct sc230ai_mode *mode,
735 struct v4l2_mbus_framefmt *framefmt)
736 {
737 return abs(mode->width - framefmt->width) +
738 abs(mode->height - framefmt->height);
739 }
740
741 static const struct sc230ai_mode *
sc230ai_find_best_fit(struct v4l2_subdev_format * fmt)742 sc230ai_find_best_fit(struct v4l2_subdev_format *fmt)
743 {
744 struct v4l2_mbus_framefmt *framefmt = &fmt->format;
745 int dist;
746 int cur_best_fit = 0;
747 int cur_best_fit_dist = -1;
748 unsigned int i;
749
750 for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
751 dist = sc230ai_get_reso_dist(&supported_modes[i], framefmt);
752 if (cur_best_fit_dist == -1 || dist < cur_best_fit_dist) {
753 cur_best_fit_dist = dist;
754 cur_best_fit = i;
755 }
756 }
757
758 return &supported_modes[cur_best_fit];
759 }
760
sc230ai_set_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)761 static int sc230ai_set_fmt(struct v4l2_subdev *sd,
762 struct v4l2_subdev_pad_config *cfg,
763 struct v4l2_subdev_format *fmt)
764 {
765 struct sc230ai *sc230ai = to_sc230ai(sd);
766 const struct sc230ai_mode *mode;
767 s64 h_blank, vblank_def;
768 u64 pixel_rate = 0;
769
770 mutex_lock(&sc230ai->mutex);
771
772 mode = sc230ai_find_best_fit(fmt);
773 fmt->format.code = mode->bus_fmt;
774 fmt->format.width = mode->width;
775 fmt->format.height = mode->height;
776 fmt->format.field = V4L2_FIELD_NONE;
777 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
778 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
779 *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
780 #else
781 mutex_unlock(&sc230ai->mutex);
782 return -ENOTTY;
783 #endif
784 } else {
785 sc230ai->cur_mode = mode;
786 h_blank = mode->hts_def - mode->width;
787 __v4l2_ctrl_modify_range(sc230ai->hblank, h_blank,
788 h_blank, 1, h_blank);
789 vblank_def = mode->vts_def - mode->height;
790 __v4l2_ctrl_modify_range(sc230ai->vblank, vblank_def,
791 SC230AI_VTS_MAX - mode->height,
792 1, vblank_def);
793
794 __v4l2_ctrl_s_ctrl(sc230ai->link_freq, mode->mipi_freq_idx);
795 pixel_rate = (u32)link_freq_menu_items[mode->mipi_freq_idx] /
796 mode->bpp * 2 * SC230AI_LANES;
797 __v4l2_ctrl_s_ctrl_int64(sc230ai->pixel_rate, pixel_rate);
798 sc230ai->cur_fps = mode->max_fps;
799 }
800
801 mutex_unlock(&sc230ai->mutex);
802
803 return 0;
804 }
805
sc230ai_get_fmt(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_format * fmt)806 static int sc230ai_get_fmt(struct v4l2_subdev *sd,
807 struct v4l2_subdev_pad_config *cfg,
808 struct v4l2_subdev_format *fmt)
809 {
810 struct sc230ai *sc230ai = to_sc230ai(sd);
811 const struct sc230ai_mode *mode = sc230ai->cur_mode;
812
813 mutex_lock(&sc230ai->mutex);
814 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
815 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
816 fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
817 #else
818 mutex_unlock(&sc230ai->mutex);
819 return -ENOTTY;
820 #endif
821 } else {
822 fmt->format.width = mode->width;
823 fmt->format.height = mode->height;
824 fmt->format.code = mode->bus_fmt;
825 fmt->format.field = V4L2_FIELD_NONE;
826 /* format info: width/height/data type/virctual channel */
827 if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
828 fmt->reserved[0] = mode->vc[fmt->pad];
829 else
830 fmt->reserved[0] = mode->vc[PAD0];
831 }
832 mutex_unlock(&sc230ai->mutex);
833
834 return 0;
835 }
836
sc230ai_enum_mbus_code(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_mbus_code_enum * code)837 static int sc230ai_enum_mbus_code(struct v4l2_subdev *sd,
838 struct v4l2_subdev_pad_config *cfg,
839 struct v4l2_subdev_mbus_code_enum *code)
840 {
841 struct sc230ai *sc230ai = to_sc230ai(sd);
842
843 if (code->index != 0)
844 return -EINVAL;
845 code->code = sc230ai->cur_mode->bus_fmt;
846
847 return 0;
848 }
849
sc230ai_enum_frame_sizes(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_size_enum * fse)850 static int sc230ai_enum_frame_sizes(struct v4l2_subdev *sd,
851 struct v4l2_subdev_pad_config *cfg,
852 struct v4l2_subdev_frame_size_enum *fse)
853 {
854 if (fse->index >= ARRAY_SIZE(supported_modes))
855 return -EINVAL;
856
857 if (fse->code != supported_modes[fse->index].bus_fmt)
858 return -EINVAL;
859
860 fse->min_width = supported_modes[fse->index].width;
861 fse->max_width = supported_modes[fse->index].width;
862 fse->max_height = supported_modes[fse->index].height;
863 fse->min_height = supported_modes[fse->index].height;
864
865 return 0;
866 }
867
sc230ai_enable_test_pattern(struct sc230ai * sc230ai,u32 pattern)868 static int sc230ai_enable_test_pattern(struct sc230ai *sc230ai, u32 pattern)
869 {
870 u32 val = 0;
871 int ret = 0;
872
873 ret = sc230ai_read_reg(sc230ai->client, SC230AI_REG_TEST_PATTERN,
874 SC230AI_REG_VALUE_08BIT, &val);
875 if (pattern)
876 val |= SC230AI_TEST_PATTERN_BIT_MASK;
877 else
878 val &= ~SC230AI_TEST_PATTERN_BIT_MASK;
879
880 ret |= sc230ai_write_reg(sc230ai->client, SC230AI_REG_TEST_PATTERN,
881 SC230AI_REG_VALUE_08BIT, val);
882 return ret;
883 }
884
sc230ai_g_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_frame_interval * fi)885 static int sc230ai_g_frame_interval(struct v4l2_subdev *sd,
886 struct v4l2_subdev_frame_interval *fi)
887 {
888 struct sc230ai *sc230ai = to_sc230ai(sd);
889 const struct sc230ai_mode *mode = sc230ai->cur_mode;
890
891 if (sc230ai->streaming)
892 fi->interval = sc230ai->cur_fps;
893 else
894 fi->interval = mode->max_fps;
895
896 return 0;
897 }
898
sc230ai_g_mbus_config(struct v4l2_subdev * sd,unsigned int pad_id,struct v4l2_mbus_config * config)899 static int sc230ai_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
900 struct v4l2_mbus_config *config)
901 {
902 struct sc230ai *sc230ai = to_sc230ai(sd);
903 const struct sc230ai_mode *mode = sc230ai->cur_mode;
904 u32 val = 1 << (SC230AI_LANES - 1) |
905 V4L2_MBUS_CSI2_CHANNEL_0 |
906 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
907
908 if (mode->hdr_mode != NO_HDR)
909 val |= V4L2_MBUS_CSI2_CHANNEL_1;
910 if (mode->hdr_mode == HDR_X3)
911 val |= V4L2_MBUS_CSI2_CHANNEL_2;
912
913 config->type = V4L2_MBUS_CSI2_DPHY;
914 config->flags = val;
915
916 return 0;
917 }
918
sc230ai_get_module_inf(struct sc230ai * sc230ai,struct rkmodule_inf * inf)919 static void sc230ai_get_module_inf(struct sc230ai *sc230ai,
920 struct rkmodule_inf *inf)
921 {
922 memset(inf, 0, sizeof(*inf));
923 strscpy(inf->base.sensor, SC230AI_NAME, sizeof(inf->base.sensor));
924 strscpy(inf->base.module, sc230ai->module_name,
925 sizeof(inf->base.module));
926 strscpy(inf->base.lens, sc230ai->len_name, sizeof(inf->base.lens));
927 }
928
sc230ai_ioctl(struct v4l2_subdev * sd,unsigned int cmd,void * arg)929 static long sc230ai_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
930 {
931 struct sc230ai *sc230ai = to_sc230ai(sd);
932 struct rkmodule_hdr_cfg *hdr;
933 u32 i, h, w;
934 long ret = 0;
935 u32 stream = 0;
936
937 switch (cmd) {
938 case RKMODULE_GET_MODULE_INFO:
939 sc230ai_get_module_inf(sc230ai, (struct rkmodule_inf *)arg);
940 break;
941 case RKMODULE_GET_HDR_CFG:
942 hdr = (struct rkmodule_hdr_cfg *)arg;
943 hdr->esp.mode = HDR_NORMAL_VC;
944 hdr->hdr_mode = sc230ai->cur_mode->hdr_mode;
945 break;
946 case RKMODULE_SET_HDR_CFG:
947 hdr = (struct rkmodule_hdr_cfg *)arg;
948 w = sc230ai->cur_mode->width;
949 h = sc230ai->cur_mode->height;
950 for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
951 if (w == supported_modes[i].width &&
952 h == supported_modes[i].height &&
953 supported_modes[i].hdr_mode == hdr->hdr_mode) {
954 sc230ai->cur_mode = &supported_modes[i];
955 break;
956 }
957 }
958 if (i == ARRAY_SIZE(supported_modes)) {
959 dev_err(&sc230ai->client->dev,
960 "not find hdr mode:%d %dx%d config\n",
961 hdr->hdr_mode, w, h);
962 ret = -EINVAL;
963 } else {
964 w = sc230ai->cur_mode->hts_def - sc230ai->cur_mode->width;
965 h = sc230ai->cur_mode->vts_def - sc230ai->cur_mode->height;
966 __v4l2_ctrl_modify_range(sc230ai->hblank, w, w, 1, w);
967 __v4l2_ctrl_modify_range(sc230ai->vblank, h,
968 SC230AI_VTS_MAX - sc230ai->cur_mode->height, 1, h);
969 sc230ai->cur_fps = sc230ai->cur_mode->max_fps;
970 }
971 break;
972 case PREISP_CMD_SET_HDRAE_EXP:
973 sc230ai_set_hdrae(sc230ai, arg);
974 break;
975 case RKMODULE_SET_QUICK_STREAM:
976
977 stream = *((u32 *)arg);
978
979 if (stream)
980 ret = sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
981 SC230AI_REG_VALUE_08BIT, SC230AI_MODE_STREAMING);
982 else
983 ret = sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
984 SC230AI_REG_VALUE_08BIT, SC230AI_MODE_SW_STANDBY);
985 break;
986 default:
987 ret = -ENOIOCTLCMD;
988 break;
989 }
990
991 return ret;
992 }
993
994 #ifdef CONFIG_COMPAT
sc230ai_compat_ioctl32(struct v4l2_subdev * sd,unsigned int cmd,unsigned long arg)995 static long sc230ai_compat_ioctl32(struct v4l2_subdev *sd,
996 unsigned int cmd, unsigned long arg)
997 {
998 void __user *up = compat_ptr(arg);
999 struct rkmodule_inf *inf;
1000 struct rkmodule_hdr_cfg *hdr;
1001 struct preisp_hdrae_exp_s *hdrae;
1002 long ret;
1003 u32 stream = 0;
1004
1005 switch (cmd) {
1006 case RKMODULE_GET_MODULE_INFO:
1007 inf = kzalloc(sizeof(*inf), GFP_KERNEL);
1008 if (!inf) {
1009 ret = -ENOMEM;
1010 return ret;
1011 }
1012
1013 ret = sc230ai_ioctl(sd, cmd, inf);
1014 if (!ret) {
1015 ret = copy_to_user(up, inf, sizeof(*inf));
1016 if (ret)
1017 return -EFAULT;
1018 }
1019 kfree(inf);
1020 break;
1021 case RKMODULE_GET_HDR_CFG:
1022 hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
1023 if (!hdr) {
1024 ret = -ENOMEM;
1025 return ret;
1026 }
1027
1028 ret = sc230ai_ioctl(sd, cmd, hdr);
1029 if (!ret) {
1030 ret = copy_to_user(up, hdr, sizeof(*hdr));
1031 if (ret)
1032 return -EFAULT;
1033 }
1034 kfree(hdr);
1035 break;
1036 case RKMODULE_SET_HDR_CFG:
1037 hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
1038 if (!hdr) {
1039 ret = -ENOMEM;
1040 return ret;
1041 }
1042
1043 if (copy_from_user(hdr, up, sizeof(*hdr))) {
1044 kfree(hdr);
1045 return -EFAULT;
1046 }
1047
1048 ret = sc230ai_ioctl(sd, cmd, hdr);
1049 kfree(hdr);
1050 break;
1051 case PREISP_CMD_SET_HDRAE_EXP:
1052 hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
1053 if (!hdrae) {
1054 ret = -ENOMEM;
1055 return ret;
1056 }
1057
1058 if (copy_from_user(hdrae, up, sizeof(*hdrae))) {
1059 kfree(hdrae);
1060 return -EFAULT;
1061 }
1062
1063 ret = sc230ai_ioctl(sd, cmd, hdrae);
1064 kfree(hdrae);
1065 break;
1066 case RKMODULE_SET_QUICK_STREAM:
1067 if (copy_from_user(&stream, up, sizeof(u32)))
1068 return -EFAULT;
1069
1070 ret = sc230ai_ioctl(sd, cmd, &stream);
1071 break;
1072 default:
1073 ret = -ENOIOCTLCMD;
1074 break;
1075 }
1076
1077 return ret;
1078 }
1079 #endif
1080
__sc230ai_start_stream(struct sc230ai * sc230ai)1081 static int __sc230ai_start_stream(struct sc230ai *sc230ai)
1082 {
1083 int ret;
1084
1085 if (!sc230ai->is_thunderboot) {
1086 ret = sc230ai_write_array(sc230ai->client, sc230ai->cur_mode->reg_list);
1087 if (ret)
1088 return ret;
1089 /* In case these controls are set before streaming */
1090 ret = __v4l2_ctrl_handler_setup(&sc230ai->ctrl_handler);
1091 if (ret)
1092 return ret;
1093 if (sc230ai->has_init_exp && sc230ai->cur_mode->hdr_mode != NO_HDR) {
1094 ret = sc230ai_ioctl(&sc230ai->subdev, PREISP_CMD_SET_HDRAE_EXP,
1095 &sc230ai->init_hdrae_exp);
1096 if (ret) {
1097 dev_err(&sc230ai->client->dev,
1098 "init exp fail in hdr mode\n");
1099 return ret;
1100 }
1101 }
1102 }
1103 return sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
1104 SC230AI_REG_VALUE_08BIT, SC230AI_MODE_STREAMING);
1105 }
1106
__sc230ai_stop_stream(struct sc230ai * sc230ai)1107 static int __sc230ai_stop_stream(struct sc230ai *sc230ai)
1108 {
1109 sc230ai->has_init_exp = false;
1110 if (sc230ai->is_thunderboot) {
1111 sc230ai->is_first_streamoff = true;
1112 pm_runtime_put(&sc230ai->client->dev);
1113 }
1114 return sc230ai_write_reg(sc230ai->client, SC230AI_REG_CTRL_MODE,
1115 SC230AI_REG_VALUE_08BIT, SC230AI_MODE_SW_STANDBY);
1116 }
1117
1118 static int __sc230ai_power_on(struct sc230ai *sc230ai);
sc230ai_s_stream(struct v4l2_subdev * sd,int on)1119 static int sc230ai_s_stream(struct v4l2_subdev *sd, int on)
1120 {
1121 struct sc230ai *sc230ai = to_sc230ai(sd);
1122 struct i2c_client *client = sc230ai->client;
1123 int ret = 0;
1124
1125 mutex_lock(&sc230ai->mutex);
1126 on = !!on;
1127 if (on == sc230ai->streaming)
1128 goto unlock_and_return;
1129
1130 if (on) {
1131 if (sc230ai->is_thunderboot && rkisp_tb_get_state() == RKISP_TB_NG) {
1132 sc230ai->is_thunderboot = false;
1133 __sc230ai_power_on(sc230ai);
1134 }
1135 ret = pm_runtime_get_sync(&client->dev);
1136 if (ret < 0) {
1137 pm_runtime_put_noidle(&client->dev);
1138 goto unlock_and_return;
1139 }
1140
1141 ret = __sc230ai_start_stream(sc230ai);
1142 if (ret) {
1143 v4l2_err(sd, "start stream failed while write regs\n");
1144 pm_runtime_put(&client->dev);
1145 goto unlock_and_return;
1146 }
1147 } else {
1148 __sc230ai_stop_stream(sc230ai);
1149 pm_runtime_put(&client->dev);
1150 }
1151
1152 sc230ai->streaming = on;
1153
1154 unlock_and_return:
1155 mutex_unlock(&sc230ai->mutex);
1156
1157 return ret;
1158 }
1159
sc230ai_s_power(struct v4l2_subdev * sd,int on)1160 static int sc230ai_s_power(struct v4l2_subdev *sd, int on)
1161 {
1162 struct sc230ai *sc230ai = to_sc230ai(sd);
1163 struct i2c_client *client = sc230ai->client;
1164 int ret = 0;
1165
1166 mutex_lock(&sc230ai->mutex);
1167
1168 /* If the power state is not modified - no work to do. */
1169 if (sc230ai->power_on == !!on)
1170 goto unlock_and_return;
1171
1172 if (on) {
1173 ret = pm_runtime_get_sync(&client->dev);
1174 if (ret < 0) {
1175 pm_runtime_put_noidle(&client->dev);
1176 goto unlock_and_return;
1177 }
1178 if (!sc230ai->is_thunderboot) {
1179 ret = sc230ai_write_array(sc230ai->client, sc230ai_global_regs);
1180 if (ret) {
1181 v4l2_err(sd, "could not set init registers\n");
1182 pm_runtime_put_noidle(&client->dev);
1183 goto unlock_and_return;
1184 }
1185 }
1186
1187 sc230ai->power_on = true;
1188 } else {
1189 pm_runtime_put(&client->dev);
1190 sc230ai->power_on = false;
1191 }
1192
1193 unlock_and_return:
1194 mutex_unlock(&sc230ai->mutex);
1195
1196 return ret;
1197 }
1198
1199 /* Calculate the delay in us by clock rate and clock cycles */
sc230ai_cal_delay(u32 cycles)1200 static inline u32 sc230ai_cal_delay(u32 cycles)
1201 {
1202 return DIV_ROUND_UP(cycles, SC230AI_XVCLK_FREQ / 1000 / 1000);
1203 }
1204
__sc230ai_power_on(struct sc230ai * sc230ai)1205 static int __sc230ai_power_on(struct sc230ai *sc230ai)
1206 {
1207 int ret;
1208 u32 delay_us;
1209 struct device *dev = &sc230ai->client->dev;
1210
1211 if (!IS_ERR_OR_NULL(sc230ai->pins_default)) {
1212 ret = pinctrl_select_state(sc230ai->pinctrl,
1213 sc230ai->pins_default);
1214 if (ret < 0)
1215 dev_err(dev, "could not set pins\n");
1216 }
1217 ret = clk_set_rate(sc230ai->xvclk, SC230AI_XVCLK_FREQ);
1218 if (ret < 0)
1219 dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
1220 if (clk_get_rate(sc230ai->xvclk) != SC230AI_XVCLK_FREQ)
1221 dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
1222 ret = clk_prepare_enable(sc230ai->xvclk);
1223 if (ret < 0) {
1224 dev_err(dev, "Failed to enable xvclk\n");
1225 return ret;
1226 }
1227 if (sc230ai->is_thunderboot)
1228 return 0;
1229
1230 if (!IS_ERR(sc230ai->reset_gpio))
1231 gpiod_set_value_cansleep(sc230ai->reset_gpio, 0);
1232
1233 ret = regulator_bulk_enable(SC230AI_NUM_SUPPLIES, sc230ai->supplies);
1234 if (ret < 0) {
1235 dev_err(dev, "Failed to enable regulators\n");
1236 goto disable_clk;
1237 }
1238
1239 if (!IS_ERR(sc230ai->reset_gpio))
1240 gpiod_set_value_cansleep(sc230ai->reset_gpio, 1);
1241
1242 usleep_range(500, 1000);
1243 if (!IS_ERR(sc230ai->pwdn_gpio))
1244 gpiod_set_value_cansleep(sc230ai->pwdn_gpio, 1);
1245
1246 if (!IS_ERR(sc230ai->reset_gpio))
1247 usleep_range(6000, 8000);
1248 else
1249 usleep_range(12000, 16000);
1250
1251 /* 8192 cycles prior to first SCCB transaction */
1252 delay_us = sc230ai_cal_delay(8192);
1253 usleep_range(delay_us, delay_us * 2);
1254
1255 return 0;
1256
1257 disable_clk:
1258 clk_disable_unprepare(sc230ai->xvclk);
1259
1260 return ret;
1261 }
1262
__sc230ai_power_off(struct sc230ai * sc230ai)1263 static void __sc230ai_power_off(struct sc230ai *sc230ai)
1264 {
1265 int ret;
1266 struct device *dev = &sc230ai->client->dev;
1267
1268 clk_disable_unprepare(sc230ai->xvclk);
1269 if (sc230ai->is_thunderboot) {
1270 if (sc230ai->is_first_streamoff) {
1271 sc230ai->is_thunderboot = false;
1272 sc230ai->is_first_streamoff = false;
1273 } else {
1274 return;
1275 }
1276 }
1277 if (!IS_ERR(sc230ai->pwdn_gpio))
1278 gpiod_set_value_cansleep(sc230ai->pwdn_gpio, 0);
1279 if (!IS_ERR(sc230ai->reset_gpio))
1280 gpiod_set_value_cansleep(sc230ai->reset_gpio, 0);
1281 if (!IS_ERR_OR_NULL(sc230ai->pins_sleep)) {
1282 ret = pinctrl_select_state(sc230ai->pinctrl,
1283 sc230ai->pins_sleep);
1284 if (ret < 0)
1285 dev_dbg(dev, "could not set pins\n");
1286 }
1287 regulator_bulk_disable(SC230AI_NUM_SUPPLIES, sc230ai->supplies);
1288 }
1289
sc230ai_runtime_resume(struct device * dev)1290 static int sc230ai_runtime_resume(struct device *dev)
1291 {
1292 struct i2c_client *client = to_i2c_client(dev);
1293 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1294 struct sc230ai *sc230ai = to_sc230ai(sd);
1295
1296 return __sc230ai_power_on(sc230ai);
1297 }
1298
sc230ai_runtime_suspend(struct device * dev)1299 static int sc230ai_runtime_suspend(struct device *dev)
1300 {
1301 struct i2c_client *client = to_i2c_client(dev);
1302 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1303 struct sc230ai *sc230ai = to_sc230ai(sd);
1304
1305 __sc230ai_power_off(sc230ai);
1306
1307 return 0;
1308 }
1309
1310 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
sc230ai_open(struct v4l2_subdev * sd,struct v4l2_subdev_fh * fh)1311 static int sc230ai_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1312 {
1313 struct sc230ai *sc230ai = to_sc230ai(sd);
1314 struct v4l2_mbus_framefmt *try_fmt =
1315 v4l2_subdev_get_try_format(sd, fh->pad, 0);
1316 const struct sc230ai_mode *def_mode = &supported_modes[0];
1317
1318 mutex_lock(&sc230ai->mutex);
1319 /* Initialize try_fmt */
1320 try_fmt->width = def_mode->width;
1321 try_fmt->height = def_mode->height;
1322 try_fmt->code = def_mode->bus_fmt;
1323 try_fmt->field = V4L2_FIELD_NONE;
1324
1325 mutex_unlock(&sc230ai->mutex);
1326 /* No crop or compose */
1327
1328 return 0;
1329 }
1330 #endif
1331
sc230ai_enum_frame_interval(struct v4l2_subdev * sd,struct v4l2_subdev_pad_config * cfg,struct v4l2_subdev_frame_interval_enum * fie)1332 static int sc230ai_enum_frame_interval(struct v4l2_subdev *sd,
1333 struct v4l2_subdev_pad_config *cfg,
1334 struct v4l2_subdev_frame_interval_enum *fie)
1335 {
1336 if (fie->index >= ARRAY_SIZE(supported_modes))
1337 return -EINVAL;
1338
1339 fie->code = supported_modes[fie->index].bus_fmt;
1340 fie->width = supported_modes[fie->index].width;
1341 fie->height = supported_modes[fie->index].height;
1342 fie->interval = supported_modes[fie->index].max_fps;
1343 fie->reserved[0] = supported_modes[fie->index].hdr_mode;
1344 return 0;
1345 }
1346
1347 static const struct dev_pm_ops sc230ai_pm_ops = {
1348 SET_RUNTIME_PM_OPS(sc230ai_runtime_suspend,
1349 sc230ai_runtime_resume, NULL)
1350 };
1351
1352 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1353 static const struct v4l2_subdev_internal_ops sc230ai_internal_ops = {
1354 .open = sc230ai_open,
1355 };
1356 #endif
1357
1358 static const struct v4l2_subdev_core_ops sc230ai_core_ops = {
1359 .s_power = sc230ai_s_power,
1360 .ioctl = sc230ai_ioctl,
1361 #ifdef CONFIG_COMPAT
1362 .compat_ioctl32 = sc230ai_compat_ioctl32,
1363 #endif
1364 };
1365
1366 static const struct v4l2_subdev_video_ops sc230ai_video_ops = {
1367 .s_stream = sc230ai_s_stream,
1368 .g_frame_interval = sc230ai_g_frame_interval,
1369 };
1370
1371 static const struct v4l2_subdev_pad_ops sc230ai_pad_ops = {
1372 .enum_mbus_code = sc230ai_enum_mbus_code,
1373 .enum_frame_size = sc230ai_enum_frame_sizes,
1374 .enum_frame_interval = sc230ai_enum_frame_interval,
1375 .get_fmt = sc230ai_get_fmt,
1376 .set_fmt = sc230ai_set_fmt,
1377 .get_mbus_config = sc230ai_g_mbus_config,
1378 };
1379
1380 static const struct v4l2_subdev_ops sc230ai_subdev_ops = {
1381 .core = &sc230ai_core_ops,
1382 .video = &sc230ai_video_ops,
1383 .pad = &sc230ai_pad_ops,
1384 };
1385
sc230ai_modify_fps_info(struct sc230ai * sc230ai)1386 static void sc230ai_modify_fps_info(struct sc230ai *sc230ai)
1387 {
1388 const struct sc230ai_mode *mode = sc230ai->cur_mode;
1389
1390 sc230ai->cur_fps.denominator = mode->max_fps.denominator * mode->vts_def /
1391 sc230ai->cur_vts;
1392 }
1393
sc230ai_set_ctrl(struct v4l2_ctrl * ctrl)1394 static int sc230ai_set_ctrl(struct v4l2_ctrl *ctrl)
1395 {
1396 struct sc230ai *sc230ai = container_of(ctrl->handler,
1397 struct sc230ai, ctrl_handler);
1398 struct i2c_client *client = sc230ai->client;
1399 u32 again = 0, dgain = 0, dgain_fine = 0x80;
1400 s64 max;
1401 int ret = 0;
1402 u32 val = 0;
1403 s32 temp = 0;
1404
1405 /* Propagate change of current control to all related controls */
1406 switch (ctrl->id) {
1407 case V4L2_CID_VBLANK:
1408 /* Update max exposure while meeting expected vblanking */
1409 max = sc230ai->cur_mode->height + ctrl->val - 4;
1410 __v4l2_ctrl_modify_range(sc230ai->exposure,
1411 sc230ai->exposure->minimum, max,
1412 sc230ai->exposure->step,
1413 sc230ai->exposure->default_value);
1414 break;
1415 }
1416
1417 if (!pm_runtime_get_if_in_use(&client->dev))
1418 return 0;
1419
1420 switch (ctrl->id) {
1421 case V4L2_CID_EXPOSURE:
1422 dev_dbg(&client->dev, "set exposure value 0x%x\n", ctrl->val);
1423 if (sc230ai->cur_mode->hdr_mode == NO_HDR) {
1424 temp = ctrl->val * 2;
1425 /* 4 least significant bits of expsoure are fractional part */
1426 ret = sc230ai_write_reg(sc230ai->client,
1427 SC230AI_REG_EXPOSURE_H,
1428 SC230AI_REG_VALUE_08BIT,
1429 SC230AI_FETCH_EXP_H(temp));
1430 ret |= sc230ai_write_reg(sc230ai->client,
1431 SC230AI_REG_EXPOSURE_M,
1432 SC230AI_REG_VALUE_08BIT,
1433 SC230AI_FETCH_EXP_M(temp));
1434 ret |= sc230ai_write_reg(sc230ai->client,
1435 SC230AI_REG_EXPOSURE_L,
1436 SC230AI_REG_VALUE_08BIT,
1437 SC230AI_FETCH_EXP_L(temp));
1438 }
1439 break;
1440 case V4L2_CID_ANALOGUE_GAIN:
1441 if (sc230ai->cur_mode->hdr_mode == NO_HDR)
1442 sc230ai_get_gain_reg(sc230ai, &again, &dgain,
1443 &dgain_fine, ctrl->val);
1444 dev_dbg(&client->dev, "gain %d, ag 0x%x, dg 0x%x, dg_f 0x%x\n",
1445 ctrl->val, again, dgain, dgain_fine);
1446 ret = sc230ai_write_reg(sc230ai->client,
1447 SC230AI_REG_ANA_GAIN,
1448 SC230AI_REG_VALUE_08BIT,
1449 again);
1450 ret |= sc230ai_write_reg(sc230ai->client,
1451 SC230AI_REG_DIG_GAIN,
1452 SC230AI_REG_VALUE_08BIT,
1453 dgain);
1454 ret |= sc230ai_write_reg(sc230ai->client,
1455 SC230AI_REG_DIG_FINE_GAIN,
1456 SC230AI_REG_VALUE_08BIT,
1457 dgain_fine);
1458 break;
1459 case V4L2_CID_VBLANK:
1460 dev_dbg(&client->dev, "set blank value 0x%x\n", ctrl->val);
1461 ret = sc230ai_write_reg(sc230ai->client,
1462 SC230AI_REG_VTS_H,
1463 SC230AI_REG_VALUE_08BIT,
1464 (ctrl->val + sc230ai->cur_mode->height)
1465 >> 8);
1466 ret |= sc230ai_write_reg(sc230ai->client,
1467 SC230AI_REG_VTS_L,
1468 SC230AI_REG_VALUE_08BIT,
1469 (ctrl->val + sc230ai->cur_mode->height)
1470 & 0xff);
1471 sc230ai->cur_vts = ctrl->val + sc230ai->cur_mode->height;
1472 sc230ai_modify_fps_info(sc230ai);
1473 break;
1474 case V4L2_CID_TEST_PATTERN:
1475 ret = sc230ai_enable_test_pattern(sc230ai, ctrl->val);
1476 break;
1477 case V4L2_CID_HFLIP:
1478 ret = sc230ai_read_reg(sc230ai->client, SC230AI_FLIP_MIRROR_REG,
1479 SC230AI_REG_VALUE_08BIT, &val);
1480 ret |= sc230ai_write_reg(sc230ai->client, SC230AI_FLIP_MIRROR_REG,
1481 SC230AI_REG_VALUE_08BIT,
1482 SC230AI_FETCH_MIRROR(val, ctrl->val));
1483 break;
1484 case V4L2_CID_VFLIP:
1485 ret = sc230ai_read_reg(sc230ai->client, SC230AI_FLIP_MIRROR_REG,
1486 SC230AI_REG_VALUE_08BIT, &val);
1487 ret |= sc230ai_write_reg(sc230ai->client, SC230AI_FLIP_MIRROR_REG,
1488 SC230AI_REG_VALUE_08BIT,
1489 SC230AI_FETCH_FLIP(val, ctrl->val));
1490 break;
1491 default:
1492 dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
1493 __func__, ctrl->id, ctrl->val);
1494 break;
1495 }
1496
1497 pm_runtime_put(&client->dev);
1498
1499 return ret;
1500 }
1501
1502 static const struct v4l2_ctrl_ops sc230ai_ctrl_ops = {
1503 .s_ctrl = sc230ai_set_ctrl,
1504 };
1505
sc230ai_initialize_controls(struct sc230ai * sc230ai)1506 static int sc230ai_initialize_controls(struct sc230ai *sc230ai)
1507 {
1508 const struct sc230ai_mode *mode;
1509 struct v4l2_ctrl_handler *handler;
1510 s64 exposure_max, vblank_def;
1511 u64 dst_pixel_rate = 0;
1512 u32 h_blank;
1513 int ret;
1514
1515 handler = &sc230ai->ctrl_handler;
1516 mode = sc230ai->cur_mode;
1517 ret = v4l2_ctrl_handler_init(handler, 9);
1518 if (ret)
1519 return ret;
1520 handler->lock = &sc230ai->mutex;
1521
1522 sc230ai->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
1523 V4L2_CID_LINK_FREQ,
1524 ARRAY_SIZE(link_freq_menu_items) - 1, 0,
1525 link_freq_menu_items);
1526 __v4l2_ctrl_s_ctrl(sc230ai->link_freq, mode->mipi_freq_idx);
1527
1528 if (mode->mipi_freq_idx == 0)
1529 dst_pixel_rate = PIXEL_RATE_WITH_371M_10BIT;
1530 else if (mode->mipi_freq_idx == 1)
1531 dst_pixel_rate = PIXEL_RATE_WITH_371M_10BIT;
1532
1533 sc230ai->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
1534 V4L2_CID_PIXEL_RATE, 0,
1535 PIXEL_RATE_WITH_371M_10BIT,
1536 1, dst_pixel_rate);
1537
1538 h_blank = mode->hts_def - mode->width;
1539 sc230ai->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
1540 h_blank, h_blank, 1, h_blank);
1541 if (sc230ai->hblank)
1542 sc230ai->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1543 vblank_def = mode->vts_def - mode->height;
1544 sc230ai->vblank = v4l2_ctrl_new_std(handler, &sc230ai_ctrl_ops,
1545 V4L2_CID_VBLANK, vblank_def,
1546 SC230AI_VTS_MAX - mode->height,
1547 1, vblank_def);
1548 exposure_max = SC230AI_EXPOSURE_LIN_MAX;
1549 sc230ai->exposure = v4l2_ctrl_new_std(handler, &sc230ai_ctrl_ops,
1550 V4L2_CID_EXPOSURE, SC230AI_EXPOSURE_MIN,
1551 exposure_max, SC230AI_EXPOSURE_STEP,
1552 mode->exp_def);
1553 sc230ai->anal_gain = v4l2_ctrl_new_std(handler, &sc230ai_ctrl_ops,
1554 V4L2_CID_ANALOGUE_GAIN, SC230AI_GAIN_MIN,
1555 SC230AI_GAIN_MAX, SC230AI_GAIN_STEP,
1556 SC230AI_GAIN_DEFAULT);
1557 sc230ai->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
1558 &sc230ai_ctrl_ops,
1559 V4L2_CID_TEST_PATTERN,
1560 ARRAY_SIZE(sc230ai_test_pattern_menu) - 1,
1561 0, 0, sc230ai_test_pattern_menu);
1562 v4l2_ctrl_new_std(handler, &sc230ai_ctrl_ops,
1563 V4L2_CID_HFLIP, 0, 1, 1, 0);
1564
1565 v4l2_ctrl_new_std(handler, &sc230ai_ctrl_ops,
1566 V4L2_CID_VFLIP, 0, 1, 1, 0);
1567
1568 if (handler->error) {
1569 ret = handler->error;
1570 dev_err(&sc230ai->client->dev,
1571 "Failed to init controls(%d)\n", ret);
1572 goto err_free_handler;
1573 }
1574
1575 sc230ai->subdev.ctrl_handler = handler;
1576 sc230ai->has_init_exp = false;
1577 sc230ai->cur_fps = mode->max_fps;
1578 return 0;
1579
1580 err_free_handler:
1581 v4l2_ctrl_handler_free(handler);
1582
1583 return ret;
1584 }
1585
sc230ai_check_sensor_id(struct sc230ai * sc230ai,struct i2c_client * client)1586 static int sc230ai_check_sensor_id(struct sc230ai *sc230ai,
1587 struct i2c_client *client)
1588 {
1589 struct device *dev = &sc230ai->client->dev;
1590 u32 id = 0;
1591 int ret;
1592
1593 if (sc230ai->is_thunderboot) {
1594 dev_info(dev, "Enable thunderboot mode, skip sensor id check\n");
1595 return 0;
1596 }
1597 ret = sc230ai_read_reg(client, SC230AI_REG_CHIP_ID,
1598 SC230AI_REG_VALUE_16BIT, &id);
1599 if (id != CHIP_ID) {
1600 dev_err(dev, "Unexpected sensor id(%06x), ret(%d)\n", id, ret);
1601 return -ENODEV;
1602 }
1603
1604 dev_info(dev, "Detected OV%06x sensor\n", CHIP_ID);
1605
1606 return 0;
1607 }
1608
sc230ai_configure_regulators(struct sc230ai * sc230ai)1609 static int sc230ai_configure_regulators(struct sc230ai *sc230ai)
1610 {
1611 unsigned int i;
1612
1613 for (i = 0; i < SC230AI_NUM_SUPPLIES; i++)
1614 sc230ai->supplies[i].supply = sc230ai_supply_names[i];
1615
1616 return devm_regulator_bulk_get(&sc230ai->client->dev,
1617 SC230AI_NUM_SUPPLIES,
1618 sc230ai->supplies);
1619 }
1620
sc230ai_probe(struct i2c_client * client,const struct i2c_device_id * id)1621 static int sc230ai_probe(struct i2c_client *client,
1622 const struct i2c_device_id *id)
1623 {
1624 struct device *dev = &client->dev;
1625 struct device_node *node = dev->of_node;
1626 struct sc230ai *sc230ai;
1627 struct v4l2_subdev *sd;
1628 char facing[2];
1629 int ret;
1630 u32 i, hdr_mode = 0;
1631
1632 dev_info(dev, "driver version: %02x.%02x.%02x",
1633 DRIVER_VERSION >> 16,
1634 (DRIVER_VERSION & 0xff00) >> 8,
1635 DRIVER_VERSION & 0x00ff);
1636
1637 sc230ai = devm_kzalloc(dev, sizeof(*sc230ai), GFP_KERNEL);
1638 if (!sc230ai)
1639 return -ENOMEM;
1640
1641 of_property_read_u32(node, OF_CAMERA_HDR_MODE, &hdr_mode);
1642 ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
1643 &sc230ai->module_index);
1644 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
1645 &sc230ai->module_facing);
1646 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
1647 &sc230ai->module_name);
1648 ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
1649 &sc230ai->len_name);
1650 if (ret) {
1651 dev_err(dev, "could not get module information!\n");
1652 return -EINVAL;
1653 }
1654 sc230ai->is_thunderboot = IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
1655 sc230ai->client = client;
1656 for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
1657 if (hdr_mode == supported_modes[i].hdr_mode) {
1658 sc230ai->cur_mode = &supported_modes[i];
1659 break;
1660 }
1661 }
1662 if (i == ARRAY_SIZE(supported_modes))
1663 sc230ai->cur_mode = &supported_modes[0];
1664
1665 sc230ai->xvclk = devm_clk_get(dev, "xvclk");
1666 if (IS_ERR(sc230ai->xvclk)) {
1667 dev_err(dev, "Failed to get xvclk\n");
1668 return -EINVAL;
1669 }
1670
1671 sc230ai->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_ASIS);
1672 if (IS_ERR(sc230ai->reset_gpio))
1673 dev_warn(dev, "Failed to get reset-gpios\n");
1674
1675 sc230ai->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_ASIS);
1676 if (IS_ERR(sc230ai->pwdn_gpio))
1677 dev_warn(dev, "Failed to get pwdn-gpios\n");
1678
1679 sc230ai->pinctrl = devm_pinctrl_get(dev);
1680 if (!IS_ERR(sc230ai->pinctrl)) {
1681 sc230ai->pins_default =
1682 pinctrl_lookup_state(sc230ai->pinctrl,
1683 OF_CAMERA_PINCTRL_STATE_DEFAULT);
1684 if (IS_ERR(sc230ai->pins_default))
1685 dev_err(dev, "could not get default pinstate\n");
1686
1687 sc230ai->pins_sleep =
1688 pinctrl_lookup_state(sc230ai->pinctrl,
1689 OF_CAMERA_PINCTRL_STATE_SLEEP);
1690 if (IS_ERR(sc230ai->pins_sleep))
1691 dev_err(dev, "could not get sleep pinstate\n");
1692 } else {
1693 dev_err(dev, "no pinctrl\n");
1694 }
1695
1696 ret = sc230ai_configure_regulators(sc230ai);
1697 if (ret) {
1698 dev_err(dev, "Failed to get power regulators\n");
1699 return ret;
1700 }
1701
1702 mutex_init(&sc230ai->mutex);
1703
1704 sd = &sc230ai->subdev;
1705 v4l2_i2c_subdev_init(sd, client, &sc230ai_subdev_ops);
1706 ret = sc230ai_initialize_controls(sc230ai);
1707 if (ret)
1708 goto err_destroy_mutex;
1709
1710 ret = __sc230ai_power_on(sc230ai);
1711 if (ret)
1712 goto err_free_handler;
1713
1714 ret = sc230ai_check_sensor_id(sc230ai, client);
1715 if (ret)
1716 goto err_power_off;
1717
1718 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1719 sd->internal_ops = &sc230ai_internal_ops;
1720 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1721 V4L2_SUBDEV_FL_HAS_EVENTS;
1722 #endif
1723 #if defined(CONFIG_MEDIA_CONTROLLER)
1724 sc230ai->pad.flags = MEDIA_PAD_FL_SOURCE;
1725 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1726 ret = media_entity_pads_init(&sd->entity, 1, &sc230ai->pad);
1727 if (ret < 0)
1728 goto err_power_off;
1729 #endif
1730
1731 memset(facing, 0, sizeof(facing));
1732 if (strcmp(sc230ai->module_facing, "back") == 0)
1733 facing[0] = 'b';
1734 else
1735 facing[0] = 'f';
1736
1737 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
1738 sc230ai->module_index, facing,
1739 SC230AI_NAME, dev_name(sd->dev));
1740 ret = v4l2_async_register_subdev_sensor_common(sd);
1741 if (ret) {
1742 dev_err(dev, "v4l2 async register subdev failed\n");
1743 goto err_clean_entity;
1744 }
1745
1746 pm_runtime_set_active(dev);
1747 pm_runtime_enable(dev);
1748 if (sc230ai->is_thunderboot)
1749 pm_runtime_get_sync(dev);
1750 else
1751 pm_runtime_idle(dev);
1752
1753 return 0;
1754
1755 err_clean_entity:
1756 #if defined(CONFIG_MEDIA_CONTROLLER)
1757 media_entity_cleanup(&sd->entity);
1758 #endif
1759 err_power_off:
1760 __sc230ai_power_off(sc230ai);
1761 err_free_handler:
1762 v4l2_ctrl_handler_free(&sc230ai->ctrl_handler);
1763 err_destroy_mutex:
1764 mutex_destroy(&sc230ai->mutex);
1765
1766 return ret;
1767 }
1768
sc230ai_remove(struct i2c_client * client)1769 static int sc230ai_remove(struct i2c_client *client)
1770 {
1771 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1772 struct sc230ai *sc230ai = to_sc230ai(sd);
1773
1774 v4l2_async_unregister_subdev(sd);
1775 #if defined(CONFIG_MEDIA_CONTROLLER)
1776 media_entity_cleanup(&sd->entity);
1777 #endif
1778 v4l2_ctrl_handler_free(&sc230ai->ctrl_handler);
1779 mutex_destroy(&sc230ai->mutex);
1780
1781 pm_runtime_disable(&client->dev);
1782 if (!pm_runtime_status_suspended(&client->dev))
1783 __sc230ai_power_off(sc230ai);
1784 pm_runtime_set_suspended(&client->dev);
1785
1786 return 0;
1787 }
1788
1789 #if IS_ENABLED(CONFIG_OF)
1790 static const struct of_device_id sc230ai_of_match[] = {
1791 { .compatible = "smartsens,sc230ai" },
1792 {},
1793 };
1794 MODULE_DEVICE_TABLE(of, sc230ai_of_match);
1795 #endif
1796
1797 static const struct i2c_device_id sc230ai_match_id[] = {
1798 { "smartsens,sc230ai", 0 },
1799 { },
1800 };
1801
1802 static struct i2c_driver sc230ai_i2c_driver = {
1803 .driver = {
1804 .name = SC230AI_NAME,
1805 .pm = &sc230ai_pm_ops,
1806 .of_match_table = of_match_ptr(sc230ai_of_match),
1807 },
1808 .probe = &sc230ai_probe,
1809 .remove = &sc230ai_remove,
1810 .id_table = sc230ai_match_id,
1811 };
1812
sensor_mod_init(void)1813 static int __init sensor_mod_init(void)
1814 {
1815 return i2c_add_driver(&sc230ai_i2c_driver);
1816 }
1817
sensor_mod_exit(void)1818 static void __exit sensor_mod_exit(void)
1819 {
1820 i2c_del_driver(&sc230ai_i2c_driver);
1821 }
1822
1823 #if defined(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP) && !defined(CONFIG_INITCALL_ASYNC)
1824 subsys_initcall(sensor_mod_init);
1825 #else
1826 device_initcall_sync(sensor_mod_init);
1827 #endif
1828 module_exit(sensor_mod_exit);
1829
1830 MODULE_DESCRIPTION("smartsens sc230ai sensor driver");
1831 MODULE_LICENSE("GPL");
1832