forked from ~ljy/RK356X_SDK_RELEASE

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