forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/media/i2c/sc2355.c
....@@ -1,18 +1,11 @@
11 // SPDX-License-Identifier: GPL-2.0
22 /*
3
- * sc2355 driver
3
+ * SC2355 driver
44 *
5
- * Copyright (C) 2020 Fuzhou Rockchip Electronics Co., Ltd.
6
- *
7
- * V0.0X01.0X00 first version,adjust sc2355.
8
- * V0.0X01.0X01 add set flip ctrl.
9
- * V0.0X01.0X02 1.fixed time limit error
10
- * 2.fixed gain conversion function
11
- * 3.fixed test pattern error
12
- * 4.add quick stream on/off
5
+ * Copyright (C) 2023 Rockchip Electronics Co., Ltd.
6
+ * V0.1.0: MIPI is ok.
137 */
148
15
-//#define DEBUG
169 #include <linux/clk.h>
1710 #include <linux/device.h>
1811 #include <linux/delay.h>
....@@ -30,87 +23,109 @@
3023 #include <media/v4l2-ctrls.h>
3124 #include <media/v4l2-subdev.h>
3225 #include <linux/pinctrl/consumer.h>
33
-#include <linux/rk-preisp.h>
3426
35
-#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x02)
36
-
27
+#define DRIVER_VERSION KERNEL_VERSION(0, 0x01, 0x00)
3728 #ifndef V4L2_CID_DIGITAL_GAIN
3829 #define V4L2_CID_DIGITAL_GAIN V4L2_CID_GAIN
3930 #endif
4031
41
-#define MIPI_FREQ_360M 360000000 //720Mbps/lane
32
+#define MIPI_FREQ_180M 180000000
33
+#define MIPI_FREQ_360M 360000000
4234
43
-#define SC2355_MAX_PIXEL_RATE (MIPI_FREQ_360M * 2 / 10)
44
-#define OF_CAMERA_HDR_MODE "rockchip,camera-hdr-mode"
35
+#define PIXEL_RATE_WITH_180M (MIPI_FREQ_180M * 2 / 10)
36
+#define PIXEL_RATE_WITH_360M (MIPI_FREQ_360M * 2 / 10)
4537
4638 #define SC2355_XVCLK_FREQ 24000000
4739
48
-#define CHIP_ID 0xeb2c
40
+#define CHIP_ID 0xeb2c
4941 #define SC2355_REG_CHIP_ID 0x3107
5042
51
-#define SC2355_REG_CTRL_MODE 0x0100
52
-#define SC2355_MODE_SW_STANDBY 0x0
53
-#define SC2355_MODE_STREAMING BIT(0)
43
+#define SC2355_REG_CTRL_MODE 0x0100
44
+#define SC2355_MODE_SW_STANDBY 0x0
45
+#define SC2355_MODE_STREAMING BIT(0)
5446
55
-#define SC2355_EXPOSURE_MIN 1// two lines long exp min
47
+#define SC2355_REG_EXPOSURE 0x3e01
48
+#define SC2355_EXPOSURE_MIN 6
5649 #define SC2355_EXPOSURE_STEP 1
5750 #define SC2355_VTS_MAX 0xffff
5851
59
-#define SC2355_REG_EXPOSURE 0x3e00 //[3:0]
52
+#define SC2355_REG_COARSE_AGAIN 0x3e09
6053
61
-//long frame and normal gain reg
62
-#define SC2355_REG_AGAIN 0x3e09
63
-#define SC2355_REG_AGAIN_FINE 0x3e09
54
+#define ANALOG_GAIN_MIN 0x01
55
+#define ANALOG_GAIN_MAX 0xF8
56
+#define ANALOG_GAIN_STEP 1
57
+#define ANALOG_GAIN_DEFAULT 0x1f
6458
65
-#define SC2355_REG_DGAIN 0x3e06
66
-#define SC2355_REG_DGAIN_FINE 0x3e07
67
-
68
-#define SC2355_GAIN_MIN 0x100
69
-#define SC2355_GAIN_MAX (128*512)
70
-#define SC2355_GAIN_STEP 1
71
-#define SC2355_GAIN_DEFAULT 0x100
72
-
73
-#define SC2355_GROUP_HOLD 0x3812
74
-#define SC2355_GROUP_UPDATE_DATA_START 0x00
75
-#define SC2355_GROUP_UPDATE_LAUNCH 0x30
76
-
77
-#define SC2355_SOFTWARE_RESET_REG 0x0103
78
-#define SC2355_REG_TEST_PATTERN 0x4501
79
-#define SC2355_TEST_PATTERN_ENABLE 0x08
59
+#define SC2355_REG_TEST_PATTERN 0x4501
60
+#define SC2355_TEST_PATTERN_ENABLE 0xcc
61
+#define SC2355_TEST_PATTERN_DISABLE 0xc4
8062
8163 #define SC2355_REG_VTS 0x320e
82
-#define SC2355_FLIP_REG 0x3221
83
-#define SC2355_FLIP_MASK 0x60
84
-#define SC2355_MIRROR_MASK 0x06
64
+
8565 #define REG_NULL 0xFFFF
8666
8767 #define SC2355_REG_VALUE_08BIT 1
8868 #define SC2355_REG_VALUE_16BIT 2
8969 #define SC2355_REG_VALUE_24BIT 3
9070
91
-#define SC2355_LANES 1
92
-#define LONG_FRAME_MAX_EXP 4297
93
-#define SHORT_FRAME_MAX_EXP 260
71
+#define SC2355_NAME "sc2355"
9472
9573 #define OF_CAMERA_PINCTRL_STATE_DEFAULT "rockchip,camera_default"
9674 #define OF_CAMERA_PINCTRL_STATE_SLEEP "rockchip,camera_sleep"
9775
98
-#define SC2355_NAME "sc2355"
76
+#define SC2355_FETCH_3RD_BYTE_EXP(VAL) (((VAL) >> 16) & 0xF) /* 4 Bits */
77
+#define SC2355_FETCH_2ND_BYTE_EXP(VAL) (((VAL) >> 8) & 0xFF) /* 8 Bits */
78
+#define SC2355_FETCH_1ST_BYTE_EXP(VAL) ((VAL) & 0xFF) /* 4 Bits */
9979
100
-static const char * const sc2355_supply_names[] = {
80
+//fps set
81
+#define SC2355_FPS (20)
82
+
83
+//default exposure
84
+#define EXP_DEFAULT_TIME_US (8000)
85
+
86
+#define SC2355_VTS_30_FPS 0x4e2
87
+
88
+#define TIME_MS 1000
89
+#define SC2355_VTS (SC2355_VTS_30_FPS * 30 / SC2355_FPS)
90
+
91
+#define SC2355_TIME_TO_EXP_LINE_US(time_us) \
92
+ (uint16_t)(time_us/1000*30*SC2355_VTS_30_FPS/TIME_MS)
93
+
94
+#define SC2355_DEFAULT_EXP_REG \
95
+ SC2355_TIME_TO_EXP_LINE_US(EXP_DEFAULT_TIME_US)
96
+
97
+#define SC2355_FSYNC_RISING_MARGIN_TIME (600)//us
98
+#define SC2355_FSYNC_RISING_MARGIN \
99
+ SC2355_TIME_TO_EXP_LINE_US(SC2355_FSYNC_RISING_MARGIN_TIME)
100
+
101
+#define SC2355_EXP_REG_TO_FSYNC_RISING(exp_reg) \
102
+ (exp_reg - 15 + SC2355_FSYNC_RISING_MARGIN)
103
+
104
+#define SC2355_DEFAULT_FSYNC_RISING \
105
+ SC2355_EXP_REG_TO_FSYNC_RISING(SC2355_DEFAULT_EXP_REG)
106
+
107
+#define SC2355_DEFAULT_FSYNC_FALLING (0x4c0)
108
+#define SC2355_DEFAULT_FSYNC_FALLING_BINNING (0x4c0/2 + 2)
109
+#define SC2355_FSYNC_RISING_REG (0x3217)
110
+
111
+#define SLAVE_MODE
112
+//slave mode max exp time (RB_ROW)
113
+#define EXP_MAX_TIME_US (13*1000)
114
+#define SC2355_SLAVE_RB_ROW SC2355_TIME_TO_EXP_LINE_US(EXP_MAX_TIME_US)
115
+
116
+#define BINNING_MODE
117
+
118
+static const char *const SC2355_supply_names[] = {
101119 "avdd", /* Analog power */
102120 "dovdd", /* Digital I/O power */
103121 "dvdd", /* Digital core power */
104122 };
105123
106
-#define SC2355_NUM_SUPPLIES ARRAY_SIZE(sc2355_supply_names)
124
+#define SC2355_NUM_SUPPLIES ARRAY_SIZE(SC2355_supply_names)
107125
108
-enum sc2355_max_pad {
109
- PAD0,
110
- PAD1,
111
- PAD2,
112
- PAD3,
113
- PAD_MAX,
126
+enum {
127
+ LINK_FREQ_180M_INDEX,
128
+ LINK_FREQ_360M_INDEX,
114129 };
115130
116131 struct regval {
....@@ -118,22 +133,21 @@
118133 u8 val;
119134 };
120135
121
-struct sc2355_mode {
122
- u32 bus_fmt;
136
+struct SC2355_mode {
123137 u32 width;
124138 u32 height;
125139 struct v4l2_fract max_fps;
126140 u32 hts_def;
127141 u32 vts_def;
128142 u32 exp_def;
143
+ u32 link_freq_index;
144
+ u64 pixel_rate;
129145 const struct regval *reg_list;
130
- u32 hdr_mode;
131
- u32 mipi_freq_idx;
132
- u32 bpp;
133
- u32 vc[PAD_MAX];
146
+ u32 lanes;
147
+ u32 bus_fmt;
134148 };
135149
136
-struct sc2355 {
150
+struct SC2355 {
137151 struct i2c_client *client;
138152 struct clk *xvclk;
139153 struct gpio_desc *reset_gpio;
....@@ -154,199 +168,366 @@
154168 struct v4l2_ctrl *pixel_rate;
155169 struct v4l2_ctrl *link_freq;
156170 struct mutex mutex;
171
+ struct v4l2_fract cur_fps;
172
+ u32 cur_vts;
157173 bool streaming;
158174 bool power_on;
159
- const struct sc2355_mode *cur_mode;
160
- u32 cfg_num;
175
+ const struct SC2355_mode *cur_mode;
161176 u32 module_index;
162177 const char *module_facing;
163178 const char *module_name;
164179 const char *len_name;
165
- bool has_init_exp;
166
- u32 cur_vts;
167
- struct preisp_hdrae_exp_s init_hdrae_exp;
168180 };
169181
170
-#define to_sc2355(sd) container_of(sd, struct sc2355, subdev)
182
+#define to_SC2355(sd) container_of(sd, struct SC2355, subdev)
171183
172184 /*
173
- * Xclk 24Mhz linear 640*480 30fps 37.125Mbps/lane
185
+ * Xclk 24Mhz
186
+ * Pclk 72Mhz
187
+ * linelength ()
188
+ * framelength ()
189
+ * grabwindow_width 800
190
+ * grabwindow_height 600
191
+ * mipi 1 lane
192
+ * max_framerate 30fps
193
+ * mipi_datarate per lane 360Mbps
174194 */
175
-static const struct regval sc2355_linear10bit_640x480_regs[] = {
176
- {0x0103, 0x01},
177
- {0x0100, 0x00},
178
- {0x36e9, 0x80},
179
- {0x36ea, 0x0f},
180
- {0x36eb, 0x24},
181
- {0x36ed, 0x14},
182
- {0x36e9, 0x01},
183
- {0x301f, 0x07},
184
- {0x303f, 0x82},
185
- {0x3200, 0x00},
186
- {0x3201, 0x9c},
187
- {0x3202, 0x00},
188
- {0x3203, 0x74},
189
- {0x3204, 0x05},
190
- {0x3205, 0xab},
191
- {0x3206, 0x04},
192
- {0x3207, 0x43},
193
- {0x3208, 0x02},
194
- {0x3209, 0x80},
195
- {0x320a, 0x01},
196
- {0x320b, 0xe0},
197
- {0x320e, 0x02},
198
- {0x320f, 0x71},
199
- {0x3210, 0x00},
200
- {0x3211, 0x04},
201
- {0x3212, 0x00},
202
- {0x3213, 0x04},
203
- {0x3215, 0x31},
204
- {0x3220, 0x01},
205
- {0x3248, 0x02},
206
- {0x3253, 0x0a},
207
- {0x3301, 0xff},
208
- {0x3302, 0xff},
209
- {0x3303, 0x10},
210
- {0x3306, 0x28},
211
- {0x3307, 0x02},
212
- {0x330a, 0x00},
213
- {0x330b, 0xb0},
214
- {0x3318, 0x02},
215
- {0x3320, 0x06},
216
- {0x3321, 0x02},
217
- {0x3326, 0x12},
218
- {0x3327, 0x0e},
219
- {0x3328, 0x03},
220
- {0x3329, 0x0f},
221
- {0x3364, 0x4f},
222
- {0x33b3, 0x40},
223
- {0x33f9, 0x2c},
224
- {0x33fb, 0x38},
225
- {0x33fc, 0x0f},
226
- {0x33fd, 0x1f},
227
- {0x349f, 0x03},
228
- {0x34a6, 0x01},
229
- {0x34a7, 0x1f},
230
- {0x34a8, 0x40},
231
- {0x34a9, 0x30},
232
- {0x34ab, 0xa6},
233
- {0x34ad, 0xa6},
234
- {0x3622, 0x60},
235
- {0x3625, 0x08},
236
- {0x3630, 0xa8},
237
- {0x3631, 0x84},
238
- {0x3632, 0x90},
239
- {0x3633, 0x43},
240
- {0x3634, 0x09},
241
- {0x3635, 0x82},
242
- {0x3636, 0x48},
243
- {0x3637, 0xe4},
244
- {0x3641, 0x22},
245
- {0x3670, 0x0f},
246
- {0x3674, 0xc0},
247
- {0x3675, 0xc0},
248
- {0x3676, 0xc0},
249
- {0x3677, 0x86},
250
- {0x3678, 0x88},
251
- {0x3679, 0x8c},
252
- {0x367c, 0x01},
253
- {0x367d, 0x0f},
254
- {0x367e, 0x01},
255
- {0x367f, 0x0f},
256
- {0x3690, 0x43},
257
- {0x3691, 0x43},
258
- {0x3692, 0x53},
259
- {0x369c, 0x01},
260
- {0x369d, 0x1f},
261
- {0x369e, 0x8a},
262
- {0x369f, 0x9e},
263
- {0x36a0, 0xda},
264
- {0x36a1, 0x01},
265
- {0x36a2, 0x03},
266
- {0x3900, 0x0d},
267
- {0x3904, 0x06},
268
- {0x3905, 0x98},
269
- {0x391b, 0x81},
270
- {0x391c, 0x10},
271
- {0x391d, 0x19},
272
- {0x3933, 0x81},
273
- {0x3934, 0x82},
274
- {0x3940, 0x91},
275
- {0x3942, 0x01},
276
- {0x3943, 0x82},
277
- {0x3949, 0xc8},
278
- {0x394b, 0x64},
279
- {0x3952, 0x02},
280
- {0x3e00, 0x00},
281
- {0x3e01, 0x26},
282
- {0x3e02, 0xb0},
283
- {0x4502, 0x34},
284
- {0x4509, 0x30},
285
- {0x4819, 0x05},
286
- {0x481b, 0x03},
287
- {0x481d, 0x0a},
288
- {0x481f, 0x02},
289
- {0x4821, 0x08},
290
- {0x4823, 0x03},
291
- {0x4825, 0x02},
292
- {0x4827, 0x03},
293
- {0x4829, 0x04},
294
- {0x5000, 0x46},
295
- {0x5900, 0x01},
296
- {0x5901, 0x04},
297
- {REG_NULL, 0x00}
195
+static const struct regval SC2355_1lane_10bit_360Mbps_800x600_30fps_regs[] = {
196
+ {0x0103,0x01},
197
+ {0x0100,0x00},
198
+ {0x36e9,0x80},
199
+ {0x36ea,0x0f},
200
+ {0x36eb,0x24},
201
+ {0x36ed,0x14},
202
+ {0x36e9,0x01},
203
+ {0x301f,0x0c},
204
+ {0x303f,0x82},
205
+ {0x3208,0x03},
206
+ {0x3209,0x20},
207
+ {0x320a,0x02},
208
+ {0x320b,0x58},
209
+ {0x3211,0x02},
210
+ {0x3213,0x02},
211
+ {0x3215,0x31},
212
+ {0x3220,0x01},
213
+ {0x3248,0x02},
214
+ {0x3253,0x0a},
215
+ {0x3301,0xff},
216
+ {0x3302,0xff},
217
+ {0x3303,0x10},
218
+ {0x3306,0x28},
219
+ {0x3307,0x02},
220
+ {0x330a,0x00},
221
+ {0x330b,0xb0},
222
+ {0x3318,0x02},
223
+ {0x3320,0x06},
224
+ {0x3321,0x02},
225
+ {0x3326,0x12},
226
+ {0x3327,0x0e},
227
+ {0x3328,0x03},
228
+ {0x3329,0x0f},
229
+ {0x3364,0x4f},
230
+ {0x33b3,0x40},
231
+ {0x33f9,0x2c},
232
+ {0x33fb,0x38},
233
+ {0x33fc,0x0f},
234
+ {0x33fd,0x1f},
235
+ {0x349f,0x03},
236
+ {0x34a6,0x01},
237
+ {0x34a7,0x1f},
238
+ {0x34a8,0x40},
239
+ {0x34a9,0x30},
240
+ {0x34ab,0xa6},
241
+ {0x34ad,0xa6},
242
+ {0x3622,0x60},
243
+ {0x3623,0x40},
244
+ {0x3624,0x61},
245
+ {0x3625,0x08},
246
+ {0x3626,0x03},
247
+ {0x3630,0xa8},
248
+ {0x3631,0x84},
249
+ {0x3632,0x90},
250
+ {0x3633,0x43},
251
+ {0x3634,0x09},
252
+ {0x3635,0x82},
253
+ {0x3636,0x48},
254
+ {0x3637,0xe4},
255
+ {0x3641,0x22},
256
+ {0x3670,0x0f},
257
+ {0x3674,0xc0},
258
+ {0x3675,0xc0},
259
+ {0x3676,0xc0},
260
+ {0x3677,0x86},
261
+ {0x3678,0x88},
262
+ {0x3679,0x8c},
263
+ {0x367c,0x01},
264
+ {0x367d,0x0f},
265
+ {0x367e,0x01},
266
+ {0x367f,0x0f},
267
+ {0x3690,0x63},
268
+ {0x3691,0x63},
269
+ {0x3692,0x73},
270
+ {0x369c,0x01},
271
+ {0x369d,0x1f},
272
+ {0x369e,0x8a},
273
+ {0x369f,0x9e},
274
+ {0x36a0,0xda},
275
+ {0x36a1,0x01},
276
+ {0x36a2,0x03},
277
+ {0x3900,0x0d},
278
+ {0x3904,0x04},
279
+ {0x3905,0x98},
280
+ {0x391b,0x81},
281
+ {0x391c,0x10},
282
+ {0x391d,0x19},
283
+ {0x3933,0x01},
284
+ {0x3934,0x82},
285
+ {0x3940,0x5d},
286
+ {0x3942,0x01},
287
+ {0x3943,0x82},
288
+ {0x3949,0xc8},
289
+ {0x394b,0x64},
290
+ {0x3952,0x02},
291
+ {0x3e00,0x00},
292
+ {0x3e01,0x4d},
293
+ {0x3e02,0xe0},
294
+ {0x4502,0x34},
295
+ {0x4509,0x30},
296
+ {0x450a,0x71},
297
+ {0x4819,0x09},
298
+ {0x481b,0x05},
299
+ {0x481d,0x13},
300
+ {0x481f,0x04},
301
+ {0x4821,0x0a},
302
+ {0x4823,0x05},
303
+ {0x4825,0x04},
304
+ {0x4827,0x05},
305
+ {0x4829,0x08},
306
+ {0x5000,0x46},
307
+ {0x5900,0xf1}, //fix noise
308
+ {0x5901,0x04},
309
+
310
+ //vts
311
+ {0x320e,(SC2355_VTS>>8)&0xff},
312
+ {0x320f,SC2355_VTS&0xff},
313
+
314
+ //exp
315
+ {0x3e00,SC2355_FETCH_3RD_BYTE_EXP(SC2355_DEFAULT_EXP_REG)},
316
+ {0x3e01,SC2355_FETCH_2ND_BYTE_EXP(SC2355_DEFAULT_EXP_REG)},
317
+ {0x3e02,SC2355_FETCH_1ST_BYTE_EXP(SC2355_DEFAULT_EXP_REG)},
318
+
319
+ //[flip]
320
+ {0x3221,0x3 << 5},
321
+
322
+ //[gain=1]
323
+ {0x3e09,0x00},
324
+
325
+ //fsync
326
+#ifndef SLAVE_MODE
327
+ {0x300b,0x44},//FSYNC out
328
+ {0x3217,SC2355_DEFAULT_FSYNC_RISING},
329
+ {0x322e,(SC2355_DEFAULT_FSYNC_FALLING_BINNING>>8)&0xff},
330
+ {0x322f,SC2355_DEFAULT_FSYNC_FALLING_BINNING&0xff},
331
+#else
332
+ {0x3222, 0x01 << 1},//slave mode
333
+ {0x300a, 0x00 << 2},//input mode
334
+
335
+ {0x3230, (SC2355_SLAVE_RB_ROW >> 8)&0xff},
336
+ {0x3231, SC2355_SLAVE_RB_ROW & 0xff},
337
+#endif
338
+
339
+ {REG_NULL, 0x00},
298340 };
299341
342
+
300343 /*
301
- * The width and height must be configured to be
302
- * the same as the current output resolution of the sensor.
303
- * The input width of the isp needs to be 16 aligned.
304
- * The input height of the isp needs to be 8 aligned.
305
- * If the width or height does not meet the alignment rules,
306
- * you can configure the cropping parameters with the following function to
307
- * crop out the appropriate resolution.
308
- * struct v4l2_subdev_pad_ops {
309
- * .get_selection
310
- * }
344
+ * Xclk 24Mhz
345
+ * Pclk 72Mhz
346
+ * linelength ()
347
+ * framelength ()
348
+ * grabwindow_width 1600
349
+ * grabwindow_height 1200
350
+ * mipi 1 lane
351
+ * max_framerate 30fps
311352 */
312
-static const struct sc2355_mode supported_modes[] = {
353
+static const struct regval SC2355_1lane_10bit_1600x1200_30fps_regs[] = {
354
+ {0x0103,0x01},
355
+ {0x0100,0x00},
356
+
357
+ {0x301f,0x01},
358
+ {0x3248,0x02},
359
+ {0x3253,0x0a},
360
+ {0x3301,0xff},
361
+ {0x3302,0xff},
362
+ {0x3303,0x10},
363
+ {0x3306,0x28},
364
+ {0x3307,0x02},
365
+ {0x330a,0x00},
366
+ {0x330b,0xb0},
367
+ {0x3318,0x02},
368
+ {0x3320,0x06},
369
+ {0x3321,0x02},
370
+ {0x3326,0x12},
371
+ {0x3327,0x0e},
372
+ {0x3328,0x03},
373
+ {0x3329,0x0f},
374
+ {0x3364,0x4f},
375
+ {0x33b3,0x40},
376
+ {0x33f9,0x2c},
377
+ {0x33fb,0x38},
378
+ {0x33fc,0x0f},
379
+ {0x33fd,0x1f},
380
+ {0x349f,0x03},
381
+ {0x34a6,0x01},
382
+ {0x34a7,0x1f},
383
+ {0x34a8,0x40},
384
+ {0x34a9,0x30},
385
+ {0x34ab,0xa6},
386
+ {0x34ad,0xa6},
387
+ {0x3622,0x60},
388
+ {0x3623,0x40},
389
+ {0x3624,0x61},
390
+ {0x3625,0x08},
391
+ {0x3626,0x03},
392
+ {0x3630,0xa8},
393
+ {0x3631,0x84},
394
+ {0x3632,0x90},
395
+ {0x3633,0x43},
396
+ {0x3634,0x09},
397
+ {0x3635,0x82},
398
+ {0x3636,0x48},
399
+ {0x3637,0xe4},
400
+ {0x3641,0x22},
401
+ {0x3670,0x0f},
402
+ {0x3674,0xc0},
403
+ {0x3675,0xc0},
404
+ {0x3676,0xc0},
405
+ {0x3677,0x86},
406
+ {0x3678,0x88},
407
+ {0x3679,0x8c},
408
+ {0x367c,0x01},
409
+ {0x367d,0x0f},
410
+ {0x367e,0x01},
411
+ {0x367f,0x0f},
412
+ {0x3690,0x63},
413
+ {0x3691,0x63},
414
+ {0x3692,0x73},
415
+ {0x369c,0x01},
416
+ {0x369d,0x1f},
417
+ {0x369e,0x8a},
418
+ {0x369f,0x9e},
419
+ {0x36a0,0xda},
420
+ {0x36a1,0x01},
421
+ {0x36a2,0x03},
422
+ {0x36e9,0x01},
423
+ {0x36ea,0x0f},
424
+ {0x36eb,0x25},
425
+ {0x36ed,0x04},
426
+ {0x3900,0x0d},
427
+ {0x3904,0x06},
428
+ {0x3905,0x98},
429
+ {0x391b,0x81},
430
+ {0x391c,0x10},
431
+ {0x391d,0x19},
432
+ {0x3933,0x01},
433
+ {0x3934,0x82},
434
+ {0x3940,0x5d},
435
+ {0x3942,0x01},
436
+ {0x3943,0x82},
437
+ {0x3949,0xc8},
438
+ {0x394b,0x64},
439
+ {0x3952,0x02},
440
+
441
+ //vts
442
+ {0x320e,(SC2355_VTS>>8)&0xff},
443
+ {0x320f,SC2355_VTS&0xff},
444
+
445
+ {0x3e00, SC2355_FETCH_3RD_BYTE_EXP(SC2355_DEFAULT_EXP_REG)},
446
+ {0x3e01, SC2355_FETCH_2ND_BYTE_EXP(SC2355_DEFAULT_EXP_REG)},
447
+ {0x3e02, SC2355_FETCH_1ST_BYTE_EXP(SC2355_DEFAULT_EXP_REG)},
448
+ {0x4502,0x34},
449
+ {0x4509,0x30},
450
+ {0x450a,0x71},
451
+
452
+ //[flip]
453
+ {0x3221,0x3 << 5},
454
+ //[gain=2]
455
+ {0x3e09,0x01},
456
+
457
+#ifndef SLAVE_MODE
458
+ {0x300b,0x44},//FSYNC out
459
+ {0x3217,SC2355_DEFAULT_FSYNC_RISING},
460
+ {0x322e,(SC2355_DEFAULT_FSYNC_FALLING>>8)&0xff},
461
+ {0x322f,SC2355_DEFAULT_FSYNC_FALLING&0xff},
462
+#else
463
+ {0x3222, 0x01 << 1},//slave mode
464
+ {0x300a, 0x00 << 2},//input mode
465
+
466
+ {0x3230, (SC2355_SLAVE_RB_ROW >> 8)&0xff},//input mode
467
+ {0x3231, SC2355_SLAVE_RB_ROW & 0xff},//input mode
468
+#endif
469
+};
470
+
471
+static const struct SC2355_mode supported_modes[] = {
472
+#ifdef BINNING_MODE
313473 {
314
- /* linear modes */
315
- .bus_fmt = MEDIA_BUS_FMT_SBGGR10_1X10,
316
- .width = 640,
317
- .height = 480,
474
+ .width = 800,
475
+ .height = 600,
318476 .max_fps = {
319477 .numerator = 10000,
320
- .denominator = 600000,
478
+ .denominator = 300000,
321479 },
322
- .exp_def = 0x026b,
323
- .hts_def = 0x0554,
324
- .vts_def = 0x0271,
325
- .reg_list = sc2355_linear10bit_640x480_regs,
326
- .hdr_mode = NO_HDR,
327
- .mipi_freq_idx = 0,
328
- .bpp = 10,
329
- .vc[PAD0] = V4L2_MBUS_CSI2_CHANNEL_0,
480
+ .exp_def = SC2355_DEFAULT_EXP_REG,
481
+ .hts_def = 0x640,
482
+ .vts_def = SC2355_VTS,
483
+ .link_freq_index = LINK_FREQ_360M_INDEX,
484
+ .pixel_rate = PIXEL_RATE_WITH_360M,
485
+ .reg_list = SC2355_1lane_10bit_360Mbps_800x600_30fps_regs,
486
+ .lanes = 1,
487
+ .bus_fmt = MEDIA_BUS_FMT_Y10_1X10,
330488 },
489
+#else
490
+ {
491
+ .width = 1600,
492
+ .height = 1200,
493
+ .max_fps = {
494
+ .numerator = 10000,
495
+ .denominator = 300000,
496
+ },
497
+ .exp_def = SC2355_DEFAULT_EXP_REG,
498
+ .hts_def = 0x640,
499
+ .vts_def = SC2355_VTS,
500
+ .link_freq_index = LINK_FREQ_360M_INDEX,
501
+ .pixel_rate = PIXEL_RATE_WITH_360M,
502
+ .reg_list = SC2355_1lane_10bit_1600x1200_30fps_regs,
503
+ .lanes = 1,
504
+ .bus_fmt = MEDIA_BUS_FMT_Y10_1X10,
505
+ },
506
+#endif
331507 };
332508
333
-static const s64 link_freq_items[] = {
509
+static const char *const SC2355_test_pattern_menu[] = {
510
+ "Disabled",
511
+ "Vertical Color Bar Type 1",
512
+ "Vertical Color Bar Type 2",
513
+ "Vertical Color Bar Type 3",
514
+ "Vertical Color Bar Type 4"
515
+};
516
+
517
+static const s64 link_freq_menu_items[] = {
518
+ MIPI_FREQ_180M,
334519 MIPI_FREQ_360M,
335520 };
336521
337
-static const char * const sc2355_test_pattern_menu[] = {
338
- "Disabled",
339
- "Vertical Color Bar Type 1"
340
-};
341
-
342522 /* Write registers up to 4 at a time */
343
-static int sc2355_write_reg(struct i2c_client *client, u16 reg,
344
- u32 len, u32 val)
523
+static int SC2355_write_reg(struct i2c_client *client,
524
+ u16 reg, u32 len, u32 val)
345525 {
346526 u32 buf_i, val_i;
347527 u8 buf[6];
348528 u8 *val_p;
349529 __be32 val_be;
530
+ u32 ret;
350531
351532 if (len > 4)
352533 return -EINVAL;
....@@ -362,30 +543,30 @@
362543 while (val_i < 4)
363544 buf[buf_i++] = val_p[val_i++];
364545
365
- if (i2c_master_send(client, buf, len + 2) != len + 2)
546
+ ret = i2c_master_send(client, buf, len + 2);
547
+ if (ret != len + 2)
366548 return -EIO;
367549
368550 return 0;
369551 }
370552
371
-static int sc2355_write_array(struct i2c_client *client,
372
- const struct regval *regs)
553
+static int SC2355_write_array(struct i2c_client *client,
554
+ const struct regval *regs)
373555 {
374556 u32 i;
375557 int ret = 0;
376558
377559 for (i = 0; ret == 0 && regs[i].addr != REG_NULL; i++) {
378
- ret |= sc2355_write_reg(client, regs[i].addr,
379
- SC2355_REG_VALUE_08BIT, regs[i].val);
560
+ ret = SC2355_write_reg(client, regs[i].addr,
561
+ SC2355_REG_VALUE_08BIT, regs[i].val);
380562 }
563
+
381564 return ret;
382565 }
383566
384567 /* Read registers up to 4 at a time */
385
-static int sc2355_read_reg(struct i2c_client *client,
386
- u16 reg,
387
- unsigned int len,
388
- u32 *val)
568
+static int SC2355_read_reg(struct i2c_client *client,
569
+ u16 reg, unsigned int len, u32 *val)
389570 {
390571 struct i2c_msg msgs[2];
391572 u8 *data_be_p;
....@@ -418,15 +599,15 @@
418599 return 0;
419600 }
420601
421
-static int sc2355_get_reso_dist(const struct sc2355_mode *mode,
422
- struct v4l2_mbus_framefmt *framefmt)
602
+static int SC2355_get_reso_dist(const struct SC2355_mode *mode,
603
+ struct v4l2_mbus_framefmt *framefmt)
423604 {
424605 return abs(mode->width - framefmt->width) +
425606 abs(mode->height - framefmt->height);
426607 }
427608
428
-static const struct sc2355_mode *
429
-sc2355_find_best_fit(struct sc2355 *sc2355, struct v4l2_subdev_format *fmt)
609
+static const struct SC2355_mode *
610
+SC2355_find_best_fit(struct v4l2_subdev_format *fmt)
430611 {
431612 struct v4l2_mbus_framefmt *framefmt = &fmt->format;
432613 int dist;
....@@ -434,10 +615,10 @@
434615 int cur_best_fit_dist = -1;
435616 unsigned int i;
436617
437
- for (i = 0; i < sc2355->cfg_num; i++) {
438
- dist = sc2355_get_reso_dist(&supported_modes[i], framefmt);
439
- if ((cur_best_fit_dist == -1 || dist <= cur_best_fit_dist) &&
440
- (supported_modes[i].bus_fmt == framefmt->code)) {
618
+ for (i = 0; i < ARRAY_SIZE(supported_modes); i++) {
619
+ dist = SC2355_get_reso_dist(&supported_modes[i], framefmt);
620
+ if ((cur_best_fit_dist == -1 || dist < cur_best_fit_dist) &&
621
+ (supported_modes[i].bus_fmt == framefmt->code)) {
441622 cur_best_fit_dist = dist;
442623 cur_best_fit = i;
443624 }
....@@ -445,26 +626,17 @@
445626 return &supported_modes[cur_best_fit];
446627 }
447628
448
-static void sc2355_change_mode(struct sc2355 *sc2355, const struct sc2355_mode *mode)
629
+static int SC2355_set_fmt(struct v4l2_subdev *sd,
630
+ struct v4l2_subdev_pad_config *cfg,
631
+ struct v4l2_subdev_format *fmt)
449632 {
450
- sc2355->cur_mode = mode;
451
- sc2355->cur_vts = sc2355->cur_mode->vts_def;
452
- dev_info(&sc2355->client->dev, "set fmt: cur_mode: %dx%d, hdr: %d\n",
453
- mode->width, mode->height, mode->hdr_mode);
454
-}
455
-
456
-static int sc2355_set_fmt(struct v4l2_subdev *sd,
457
- struct v4l2_subdev_pad_config *cfg,
458
- struct v4l2_subdev_format *fmt)
459
-{
460
- struct sc2355 *sc2355 = to_sc2355(sd);
461
- const struct sc2355_mode *mode;
633
+ struct SC2355 *SC2355 = to_SC2355(sd);
634
+ const struct SC2355_mode *mode;
462635 s64 h_blank, vblank_def;
463
- u64 pixel_rate = 0;
464636
465
- mutex_lock(&sc2355->mutex);
637
+ mutex_lock(&SC2355->mutex);
466638
467
- mode = sc2355_find_best_fit(sc2355, fmt);
639
+ mode = SC2355_find_best_fit(fmt);
468640 fmt->format.code = mode->bus_fmt;
469641 fmt->format.width = mode->width;
470642 fmt->format.height = mode->height;
....@@ -473,40 +645,42 @@
473645 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
474646 *v4l2_subdev_get_try_format(sd, cfg, fmt->pad) = fmt->format;
475647 #else
476
- mutex_unlock(&sc2355->mutex);
648
+ mutex_unlock(&SC2355->mutex);
477649 return -ENOTTY;
478650 #endif
479651 } else {
480
- sc2355_change_mode(sc2355, mode);
652
+ SC2355->cur_mode = mode;
481653 h_blank = mode->hts_def - mode->width;
482
- __v4l2_ctrl_modify_range(sc2355->hblank, h_blank,
654
+ __v4l2_ctrl_modify_range(SC2355->hblank, h_blank,
483655 h_blank, 1, h_blank);
484656 vblank_def = mode->vts_def - mode->height;
485
- __v4l2_ctrl_modify_range(sc2355->vblank, vblank_def,
657
+ __v4l2_ctrl_modify_range(SC2355->vblank, vblank_def,
486658 SC2355_VTS_MAX - mode->height,
487659 1, vblank_def);
488
- __v4l2_ctrl_s_ctrl(sc2355->link_freq, mode->mipi_freq_idx);
489
- pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
490
- mode->bpp * 2 * SC2355_LANES;
491
- __v4l2_ctrl_s_ctrl_int64(sc2355->pixel_rate, pixel_rate);
660
+ __v4l2_ctrl_s_ctrl_int64(SC2355->pixel_rate, mode->pixel_rate);
661
+ __v4l2_ctrl_s_ctrl(SC2355->link_freq, mode->link_freq_index);
662
+ SC2355->cur_vts = mode->vts_def;
663
+ SC2355->cur_fps = mode->max_fps;
492664 }
493
- mutex_unlock(&sc2355->mutex);
665
+
666
+ mutex_unlock(&SC2355->mutex);
667
+
494668 return 0;
495669 }
496670
497
-static int sc2355_get_fmt(struct v4l2_subdev *sd,
498
- struct v4l2_subdev_pad_config *cfg,
499
- struct v4l2_subdev_format *fmt)
671
+static int SC2355_get_fmt(struct v4l2_subdev *sd,
672
+ struct v4l2_subdev_pad_config *cfg,
673
+ struct v4l2_subdev_format *fmt)
500674 {
501
- struct sc2355 *sc2355 = to_sc2355(sd);
502
- const struct sc2355_mode *mode = sc2355->cur_mode;
675
+ struct SC2355 *SC2355 = to_SC2355(sd);
676
+ const struct SC2355_mode *mode = SC2355->cur_mode;
503677
504
- mutex_lock(&sc2355->mutex);
678
+ mutex_lock(&SC2355->mutex);
505679 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
506680 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
507681 fmt->format = *v4l2_subdev_get_try_format(sd, cfg, fmt->pad);
508682 #else
509
- mutex_unlock(&sc2355->mutex);
683
+ mutex_unlock(&SC2355->mutex);
510684 return -ENOTTY;
511685 #endif
512686 } else {
....@@ -514,231 +688,86 @@
514688 fmt->format.height = mode->height;
515689 fmt->format.code = mode->bus_fmt;
516690 fmt->format.field = V4L2_FIELD_NONE;
517
- if (fmt->pad < PAD_MAX && mode->hdr_mode != NO_HDR)
518
- fmt->reserved[0] = mode->vc[fmt->pad];
519
- else
520
- fmt->reserved[0] = mode->vc[PAD0];
521691 }
522
- mutex_unlock(&sc2355->mutex);
692
+ mutex_unlock(&SC2355->mutex);
523693
524694 return 0;
525695 }
526696
527
-static int sc2355_enum_mbus_code(struct v4l2_subdev *sd,
528
- struct v4l2_subdev_pad_config *cfg,
529
- struct v4l2_subdev_mbus_code_enum *code)
697
+static int SC2355_enum_mbus_code(struct v4l2_subdev *sd,
698
+ struct v4l2_subdev_pad_config *cfg,
699
+ struct v4l2_subdev_mbus_code_enum *code)
530700 {
531
- struct sc2355 *sc2355 = to_sc2355(sd);
701
+ struct SC2355 *SC2355 = to_SC2355(sd);
532702
533703 if (code->index != 0)
534704 return -EINVAL;
535
- code->code = sc2355->cur_mode->bus_fmt;
705
+ code->code = SC2355->cur_mode->bus_fmt;
536706
537707 return 0;
538708 }
539709
540
-static int sc2355_enum_frame_sizes(struct v4l2_subdev *sd,
541
- struct v4l2_subdev_pad_config *cfg,
542
- struct v4l2_subdev_frame_size_enum *fse)
710
+static int SC2355_enum_frame_sizes(struct v4l2_subdev *sd,
711
+ struct v4l2_subdev_pad_config *cfg,
712
+ struct v4l2_subdev_frame_size_enum *fse)
543713 {
544
- struct sc2355 *sc2355 = to_sc2355(sd);
545
-
546
- if (fse->index >= sc2355->cfg_num)
714
+ if (fse->index >= ARRAY_SIZE(supported_modes))
547715 return -EINVAL;
548716
549717 if (fse->code != supported_modes[fse->index].bus_fmt)
550718 return -EINVAL;
551719
552
- fse->min_width = supported_modes[fse->index].width;
553
- fse->max_width = supported_modes[fse->index].width;
720
+ fse->min_width = supported_modes[fse->index].width;
721
+ fse->max_width = supported_modes[fse->index].width;
554722 fse->max_height = supported_modes[fse->index].height;
555723 fse->min_height = supported_modes[fse->index].height;
556724
557725 return 0;
558726 }
559727
560
-static int sc2355_enable_test_pattern(struct sc2355 *sc2355, u32 pattern)
728
+static int SC2355_enable_test_pattern(struct SC2355 *SC2355, u32 pattern)
561729 {
562
- u32 val = 0;
563
- int ret = 0;
730
+ u32 val;
564731
565
- ret = sc2355_read_reg(sc2355->client, SC2355_REG_TEST_PATTERN,
566
- SC2355_REG_VALUE_08BIT, &val);
567732 if (pattern)
568
- val |= SC2355_TEST_PATTERN_ENABLE;
733
+ val = (pattern - 1) | SC2355_TEST_PATTERN_ENABLE;
569734 else
570
- val &= ~SC2355_TEST_PATTERN_ENABLE;
571
- ret |= sc2355_write_reg(sc2355->client, SC2355_REG_TEST_PATTERN,
572
- SC2355_REG_VALUE_08BIT, val);
573
- return ret;
735
+ val = SC2355_TEST_PATTERN_DISABLE;
736
+
737
+ return SC2355_write_reg(SC2355->client, SC2355_REG_TEST_PATTERN,
738
+ SC2355_REG_VALUE_08BIT, val);
574739 }
575740
576
-static int sc2355_g_frame_interval(struct v4l2_subdev *sd,
577
- struct v4l2_subdev_frame_interval *fi)
578
-{
579
- struct sc2355 *sc2355 = to_sc2355(sd);
580
- const struct sc2355_mode *mode = sc2355->cur_mode;
581
-
582
- mutex_lock(&sc2355->mutex);
583
- fi->interval = mode->max_fps;
584
- mutex_unlock(&sc2355->mutex);
585
-
586
- return 0;
587
-}
588
-
589
-static int sc2355_g_mbus_config(struct v4l2_subdev *sd,
590
- struct v4l2_mbus_config *config)
591
-{
592
- struct sc2355 *sc2355 = to_sc2355(sd);
593
- const struct sc2355_mode *mode = sc2355->cur_mode;
594
- u32 val = 0;
595
-
596
- if (mode->hdr_mode == NO_HDR)
597
- val = 1 << (SC2355_LANES - 1) |
598
- V4L2_MBUS_CSI2_CHANNEL_0 |
599
- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
600
- if (mode->hdr_mode == HDR_X2)
601
- val = 1 << (SC2355_LANES - 1) |
602
- V4L2_MBUS_CSI2_CHANNEL_0 |
603
- V4L2_MBUS_CSI2_CONTINUOUS_CLOCK |
604
- V4L2_MBUS_CSI2_CHANNEL_1;
605
-
606
- config->type = V4L2_MBUS_CSI2;
607
- config->flags = val;
608
-
609
- return 0;
610
-}
611
-
612
-static void sc2355_get_module_inf(struct sc2355 *sc2355,
613
- struct rkmodule_inf *inf)
741
+static void SC2355_get_module_inf(struct SC2355 *SC2355,
742
+ struct rkmodule_inf *inf)
614743 {
615744 memset(inf, 0, sizeof(*inf));
616745 strscpy(inf->base.sensor, SC2355_NAME, sizeof(inf->base.sensor));
617
- strscpy(inf->base.module, sc2355->module_name,
746
+ strscpy(inf->base.module, SC2355->module_name,
618747 sizeof(inf->base.module));
619
- strscpy(inf->base.lens, sc2355->len_name, sizeof(inf->base.lens));
748
+ strscpy(inf->base.lens, SC2355->len_name, sizeof(inf->base.lens));
620749 }
621750
622
-
623
-static void sc2355_get_gain(u32 total_gain, u32 *again_reg, u32 *dgain_reg, u32 *dgain_fine_reg)
751
+static long SC2355_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
624752 {
625
- u32 again = 0;
626
- u32 dgain = 0, dgain_fine = 0;
627
-
628
- if (total_gain < 0x0100) {/* 1x gain ~ 2x gain */
629
- again = 0x00;
630
-
631
- dgain = 0x00;
632
- dgain_fine = total_gain;
633
- } else if (total_gain < 0x0200) { /* 2x gain ~ 4x gain */
634
- again = 0x01;
635
-
636
- dgain = 0x00;
637
- dgain_fine = total_gain >> 1;
638
- } else if (total_gain < 0x0400) { /* 4x gain ~ 8x gain */
639
- again = 0x03;
640
-
641
- dgain = 0x00;
642
- dgain_fine = total_gain >> 2;
643
- } else if (total_gain < 0x0800) { /* 8x gain ~ 16x gain */
644
- again = 0x07;
645
-
646
- dgain = 0x00;
647
- dgain_fine = total_gain >> 3;
648
- } else if (total_gain < 0x1000) { /* 16x gain ~ 32x gain */
649
- again = 0xF;
650
-
651
- dgain = 0x00;
652
- dgain_fine = total_gain >> 4;
653
- } else if (total_gain < 0x2000) { /* 32x gain ~ 64x gain */
654
- again = 0x1F;
655
-
656
- dgain = 0x00;
657
- dgain_fine = total_gain >> 5;
658
- } else if (total_gain < 0x4000) { /* 64x gain ~ 128x gain */
659
- again = 0x1F;
660
-
661
- dgain = 0x01;
662
- dgain_fine = total_gain >> 6;
663
- } else if (total_gain < 0x8000) { /* 128x gain ~ 256x gain */
664
- again = 0x1F;
665
-
666
- dgain = 0x03;
667
- dgain_fine = total_gain >> 7;
668
- }
669
-
670
- *again_reg = again;
671
- *dgain_reg = dgain;
672
- *dgain_fine_reg = dgain_fine;
673
-}
674
-static long sc2355_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
675
-{
676
- struct sc2355 *sc2355 = to_sc2355(sd);
677
- struct rkmodule_hdr_cfg *hdr_cfg;
678
- const struct sc2355_mode *mode;
753
+ struct SC2355 *SC2355 = to_SC2355(sd);
679754 long ret = 0;
680
- u64 pixel_rate = 0;
681
- u32 i, h, w, stream;
755
+ u32 stream = 0;
682756
683757 switch (cmd) {
684
- case RKMODULE_SET_HDR_CFG:
685
- hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
686
- if (sc2355->streaming) {
687
- ret = sc2355_write_array(sc2355->client, sc2355->cur_mode->reg_list);
688
- if (ret)
689
- return ret;
690
- }
691
- w = sc2355->cur_mode->width;
692
- h = sc2355->cur_mode->height;
693
- for (i = 0; i < sc2355->cfg_num; i++) {
694
- if (w == supported_modes[i].width &&
695
- h == supported_modes[i].height &&
696
- supported_modes[i].hdr_mode == hdr_cfg->hdr_mode) {
697
- sc2355_change_mode(sc2355, &supported_modes[i]);
698
- break;
699
- }
700
- }
701
-
702
- if (i == sc2355->cfg_num) {
703
- dev_err(&sc2355->client->dev,
704
- "not find hdr mode:%d %dx%d config\n",
705
- hdr_cfg->hdr_mode, w, h);
706
- ret = -EINVAL;
707
- } else {
708
- mode = sc2355->cur_mode;
709
- w = mode->hts_def - mode->width;
710
- h = mode->vts_def - mode->height;
711
- __v4l2_ctrl_modify_range(sc2355->hblank, w, w, 1, w);
712
- __v4l2_ctrl_modify_range(sc2355->vblank, h,
713
- SC2355_VTS_MAX - mode->height,
714
- 1, h);
715
- __v4l2_ctrl_s_ctrl(sc2355->link_freq, mode->mipi_freq_idx);
716
- pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] /
717
- mode->bpp * 2 * SC2355_LANES;
718
- __v4l2_ctrl_s_ctrl_int64(sc2355->pixel_rate,
719
- pixel_rate);
720
- dev_info(&sc2355->client->dev,
721
- "sensor mode: %d\n", mode->hdr_mode);
722
- }
723
- break;
724758 case RKMODULE_GET_MODULE_INFO:
725
- sc2355_get_module_inf(sc2355, (struct rkmodule_inf *)arg);
726
- break;
727
- case RKMODULE_GET_HDR_CFG:
728
- hdr_cfg = (struct rkmodule_hdr_cfg *)arg;
729
- hdr_cfg->esp.mode = HDR_NORMAL_VC;
730
- hdr_cfg->hdr_mode = sc2355->cur_mode->hdr_mode;
759
+ SC2355_get_module_inf(SC2355, (struct rkmodule_inf *)arg);
731760 break;
732761 case RKMODULE_SET_QUICK_STREAM:
733762
734763 stream = *((u32 *)arg);
735764
736765 if (stream)
737
- ret = sc2355_write_reg(sc2355->client, SC2355_REG_CTRL_MODE,
738
- SC2355_REG_VALUE_08BIT, SC2355_MODE_STREAMING);
766
+ ret = SC2355_write_reg(SC2355->client, SC2355_REG_CTRL_MODE,
767
+ SC2355_REG_VALUE_08BIT, SC2355_MODE_STREAMING);
739768 else
740
- ret = sc2355_write_reg(sc2355->client, SC2355_REG_CTRL_MODE,
741
- SC2355_REG_VALUE_08BIT, SC2355_MODE_SW_STANDBY);
769
+ ret = SC2355_write_reg(SC2355->client, SC2355_REG_CTRL_MODE,
770
+ SC2355_REG_VALUE_08BIT, SC2355_MODE_SW_STANDBY);
742771 break;
743772 default:
744773 ret = -ENOIOCTLCMD;
....@@ -749,16 +778,12 @@
749778 }
750779
751780 #ifdef CONFIG_COMPAT
752
-static long sc2355_compat_ioctl32(struct v4l2_subdev *sd,
753
- unsigned int cmd, unsigned long arg)
781
+static long SC2355_compat_ioctl32(struct v4l2_subdev *sd,
782
+ unsigned int cmd, unsigned long arg)
754783 {
755784 void __user *up = compat_ptr(arg);
756785 struct rkmodule_inf *inf;
757
- struct rkmodule_awb_cfg *cfg;
758
- struct rkmodule_hdr_cfg *hdr;
759
- struct preisp_hdrae_exp_s *hdrae;
760786 long ret = 0;
761
- u32 cg = 0;
762787 u32 stream = 0;
763788
764789 switch (cmd) {
....@@ -769,80 +794,19 @@
769794 return ret;
770795 }
771796
772
- ret = sc2355_ioctl(sd, cmd, inf);
797
+ ret = SC2355_ioctl(sd, cmd, inf);
773798 if (!ret) {
774799 ret = copy_to_user(up, inf, sizeof(*inf));
775800 if (ret)
776
- return -EFAULT;
801
+ ret = -EFAULT;
777802 }
778803 kfree(inf);
779
- break;
780
- case RKMODULE_AWB_CFG:
781
- cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
782
- if (!cfg) {
783
- ret = -ENOMEM;
784
- return ret;
785
- }
786
-
787
- if (copy_from_user(cfg, up, sizeof(*cfg))) {
788
- kfree(cfg);
789
- return -EFAULT;
790
- }
791
- ret = sc2355_ioctl(sd, cmd, cfg);
792
- kfree(cfg);
793
- break;
794
- case RKMODULE_GET_HDR_CFG:
795
- hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
796
- if (!hdr) {
797
- ret = -ENOMEM;
798
- return ret;
799
- }
800
-
801
- ret = sc2355_ioctl(sd, cmd, hdr);
802
- if (!ret) {
803
- ret = copy_to_user(up, hdr, sizeof(*hdr));
804
- if (ret)
805
- return -EFAULT;
806
- }
807
- kfree(hdr);
808
- break;
809
- case RKMODULE_SET_HDR_CFG:
810
- hdr = kzalloc(sizeof(*hdr), GFP_KERNEL);
811
- if (!hdr) {
812
- ret = -ENOMEM;
813
- return ret;
814
- }
815
-
816
- if (copy_from_user(hdr, up, sizeof(*hdr))) {
817
- kfree(hdr);
818
- return -EFAULT;
819
- }
820
- ret = sc2355_ioctl(sd, cmd, hdr);
821
- kfree(hdr);
822
- break;
823
- case PREISP_CMD_SET_HDRAE_EXP:
824
- hdrae = kzalloc(sizeof(*hdrae), GFP_KERNEL);
825
- if (!hdrae) {
826
- ret = -ENOMEM;
827
- return ret;
828
- }
829
-
830
- if (copy_from_user(hdrae, up, sizeof(*hdrae))) {
831
- kfree(hdrae);
832
- return -EFAULT;
833
- }
834
- ret = sc2355_ioctl(sd, cmd, hdrae);
835
- kfree(hdrae);
836
- break;
837
- case RKMODULE_SET_CONVERSION_GAIN:
838
- if (copy_from_user(&cg, up, sizeof(cg)))
839
- return -EFAULT;
840
- ret = sc2355_ioctl(sd, cmd, &cg);
841804 break;
842805 case RKMODULE_SET_QUICK_STREAM:
843806 if (copy_from_user(&stream, up, sizeof(u32)))
844807 return -EFAULT;
845
- ret = sc2355_ioctl(sd, cmd, &stream);
808
+
809
+ ret = SC2355_ioctl(sd, cmd, &stream);
846810 break;
847811 default:
848812 ret = -ENOIOCTLCMD;
....@@ -853,50 +817,69 @@
853817 }
854818 #endif
855819
856
-static int __sc2355_start_stream(struct sc2355 *sc2355)
820
+static int SC2355_set_ctrl_gain(struct SC2355 *SC2355, u32 a_gain)
821
+{
822
+ int ret = 0;
823
+
824
+ if (a_gain > 1)
825
+ a_gain = ((a_gain + 1) >> 1) << 1;
826
+ a_gain -=1;
827
+
828
+ ret |= SC2355_write_reg(SC2355->client,
829
+ SC2355_REG_COARSE_AGAIN,
830
+ SC2355_REG_VALUE_08BIT,
831
+ a_gain);
832
+
833
+ return ret;
834
+}
835
+
836
+
837
+static int __SC2355_start_stream(struct SC2355 *SC2355)
857838 {
858839 int ret;
859840
860
- ret = sc2355_write_array(sc2355->client, sc2355->cur_mode->reg_list);
861
- if (ret)
862
- return ret;
863
-
864
- ret = __v4l2_ctrl_handler_setup(&sc2355->ctrl_handler);
841
+ ret = SC2355_write_array(SC2355->client, SC2355->cur_mode->reg_list);
865842 if (ret)
866843 return ret;
867844
868845 /* In case these controls are set before streaming */
869
- if (sc2355->has_init_exp && sc2355->cur_mode->hdr_mode != NO_HDR) {
870
- ret = sc2355_ioctl(&sc2355->subdev, PREISP_CMD_SET_HDRAE_EXP,
871
- &sc2355->init_hdrae_exp);
872
- if (ret) {
873
- dev_err(&sc2355->client->dev,
874
- "init exp fail in hdr mode\n");
875
- return ret;
876
- }
877
- }
846
+ mutex_unlock(&SC2355->mutex);
847
+ ret = v4l2_ctrl_handler_setup(&SC2355->ctrl_handler);
848
+ mutex_lock(&SC2355->mutex);
849
+ if (ret)
850
+ return ret;
878851
879
- return sc2355_write_reg(sc2355->client, SC2355_REG_CTRL_MODE,
880
- SC2355_REG_VALUE_08BIT, SC2355_MODE_STREAMING);
852
+ ret = SC2355_write_reg(SC2355->client, SC2355_REG_CTRL_MODE,
853
+ SC2355_REG_VALUE_08BIT, SC2355_MODE_STREAMING);
854
+
855
+ return ret;
881856 }
882857
883
-static int __sc2355_stop_stream(struct sc2355 *sc2355)
858
+static int __SC2355_stop_stream(struct SC2355 *SC2355)
884859 {
885
- sc2355->has_init_exp = false;
886
- return sc2355_write_reg(sc2355->client, SC2355_REG_CTRL_MODE,
887
- SC2355_REG_VALUE_08BIT, SC2355_MODE_SW_STANDBY);
860
+ return SC2355_write_reg(SC2355->client, SC2355_REG_CTRL_MODE,
861
+ SC2355_REG_VALUE_08BIT, SC2355_MODE_SW_STANDBY);
888862 }
889863
890
-static int sc2355_s_stream(struct v4l2_subdev *sd, int on)
864
+static int SC2355_s_stream(struct v4l2_subdev *sd, int on)
891865 {
892
- struct sc2355 *sc2355 = to_sc2355(sd);
893
- struct i2c_client *client = sc2355->client;
866
+ struct SC2355 *SC2355 = to_SC2355(sd);
867
+ struct i2c_client *client = SC2355->client;
868
+ unsigned int fps;
894869 int ret = 0;
895870
896
- mutex_lock(&sc2355->mutex);
871
+ mutex_lock(&SC2355->mutex);
897872 on = !!on;
898
- if (on == sc2355->streaming)
873
+ if (on == SC2355->streaming)
899874 goto unlock_and_return;
875
+
876
+ fps = DIV_ROUND_CLOSEST(SC2355->cur_mode->max_fps.denominator,
877
+ SC2355->cur_mode->max_fps.numerator);
878
+
879
+ dev_info(&SC2355->client->dev, "%s: on: %d, %dx%d@%d\n", __func__, on,
880
+ SC2355->cur_mode->width,
881
+ SC2355->cur_mode->height,
882
+ fps);
900883
901884 if (on) {
902885 ret = pm_runtime_get_sync(&client->dev);
....@@ -905,35 +888,35 @@
905888 goto unlock_and_return;
906889 }
907890
908
- ret = __sc2355_start_stream(sc2355);
891
+ ret = __SC2355_start_stream(SC2355);
909892 if (ret) {
910893 v4l2_err(sd, "start stream failed while write regs\n");
911894 pm_runtime_put(&client->dev);
912895 goto unlock_and_return;
913896 }
914897 } else {
915
- __sc2355_stop_stream(sc2355);
898
+ __SC2355_stop_stream(SC2355);
916899 pm_runtime_put(&client->dev);
917900 }
918901
919
- sc2355->streaming = on;
902
+ SC2355->streaming = on;
920903
921904 unlock_and_return:
922
- mutex_unlock(&sc2355->mutex);
905
+ mutex_unlock(&SC2355->mutex);
923906
924907 return ret;
925908 }
926909
927
-static int sc2355_s_power(struct v4l2_subdev *sd, int on)
910
+static int SC2355_s_power(struct v4l2_subdev *sd, int on)
928911 {
929
- struct sc2355 *sc2355 = to_sc2355(sd);
930
- struct i2c_client *client = sc2355->client;
912
+ struct SC2355 *SC2355 = to_SC2355(sd);
913
+ struct i2c_client *client = SC2355->client;
931914 int ret = 0;
932915
933
- mutex_lock(&sc2355->mutex);
916
+ mutex_lock(&SC2355->mutex);
934917
935918 /* If the power state is not modified - no work to do. */
936
- if (sc2355->power_on == !!on)
919
+ if (SC2355->power_on == !!on)
937920 goto unlock_and_return;
938921
939922 if (on) {
....@@ -942,282 +925,290 @@
942925 pm_runtime_put_noidle(&client->dev);
943926 goto unlock_and_return;
944927 }
945
-
946
- ret |= sc2355_write_reg(sc2355->client,
947
- SC2355_SOFTWARE_RESET_REG,
948
- SC2355_REG_VALUE_08BIT,
949
- 0x01);
950
- usleep_range(100, 200);
951
-
952
- sc2355->power_on = true;
928
+ SC2355->power_on = true;
953929 } else {
954930 pm_runtime_put(&client->dev);
955
- sc2355->power_on = false;
931
+ SC2355->power_on = false;
956932 }
957933
958934 unlock_and_return:
959
- mutex_unlock(&sc2355->mutex);
935
+ mutex_unlock(&SC2355->mutex);
960936
961937 return ret;
962938 }
963939
964
-static int __sc2355_power_on(struct sc2355 *sc2355)
940
+static int SC2355_g_frame_interval(struct v4l2_subdev *sd,
941
+ struct v4l2_subdev_frame_interval *fi)
942
+{
943
+ struct SC2355 *SC2355 = to_SC2355(sd);
944
+ const struct SC2355_mode *mode = SC2355->cur_mode;
945
+
946
+ if (SC2355->streaming)
947
+ fi->interval = SC2355->cur_fps;
948
+ else
949
+ fi->interval = mode->max_fps;
950
+
951
+ return 0;
952
+}
953
+
954
+/* Calculate the delay in us by clock rate and clock cycles */
955
+static inline u32 SC2355_cal_delay(u32 cycles)
956
+{
957
+ return DIV_ROUND_UP(cycles, SC2355_XVCLK_FREQ / 1000 / 1000);
958
+}
959
+
960
+static int __SC2355_power_on(struct SC2355 *SC2355)
965961 {
966962 int ret;
967
- struct device *dev = &sc2355->client->dev;
963
+ u32 delay_us;
964
+ struct device *dev = &SC2355->client->dev;
968965
969
- if (!IS_ERR_OR_NULL(sc2355->pins_default)) {
970
- ret = pinctrl_select_state(sc2355->pinctrl,
971
- sc2355->pins_default);
966
+ if (!IS_ERR_OR_NULL(SC2355->pins_default)) {
967
+ ret = pinctrl_select_state(SC2355->pinctrl,
968
+ SC2355->pins_default);
972969 if (ret < 0)
973970 dev_err(dev, "could not set pins\n");
974971 }
975
- ret = clk_set_rate(sc2355->xvclk, SC2355_XVCLK_FREQ);
972
+
973
+ ret = clk_set_rate(SC2355->xvclk, SC2355_XVCLK_FREQ);
976974 if (ret < 0)
977975 dev_warn(dev, "Failed to set xvclk rate (24MHz)\n");
978
- if (clk_get_rate(sc2355->xvclk) != SC2355_XVCLK_FREQ)
976
+ if (clk_get_rate(SC2355->xvclk) != SC2355_XVCLK_FREQ)
979977 dev_warn(dev, "xvclk mismatched, modes are based on 24MHz\n");
980
- ret = clk_prepare_enable(sc2355->xvclk);
978
+ ret = clk_prepare_enable(SC2355->xvclk);
981979 if (ret < 0) {
982980 dev_err(dev, "Failed to enable xvclk\n");
983981 return ret;
984982 }
985
- if (!IS_ERR(sc2355->reset_gpio))
986
- gpiod_set_value_cansleep(sc2355->reset_gpio, 1);
987983
988
- ret = regulator_bulk_enable(SC2355_NUM_SUPPLIES, sc2355->supplies);
984
+ ret = regulator_bulk_enable(SC2355_NUM_SUPPLIES, SC2355->supplies);
989985 if (ret < 0) {
990986 dev_err(dev, "Failed to enable regulators\n");
991987 goto disable_clk;
992988 }
993989
994
- if (!IS_ERR(sc2355->reset_gpio))
995
- gpiod_set_value_cansleep(sc2355->reset_gpio, 0);
990
+ if (!IS_ERR(SC2355->reset_gpio))
991
+ gpiod_set_value_cansleep(SC2355->reset_gpio, 1);
996992
997
- usleep_range(500, 1000);
998
- if (!IS_ERR(sc2355->pwdn_gpio))
999
- gpiod_set_value_cansleep(sc2355->pwdn_gpio, 0);
1000
- usleep_range(2000, 4000);
993
+ usleep_range(1000, 2000);
994
+
995
+ if (!IS_ERR(SC2355->pwdn_gpio))
996
+ gpiod_set_value_cansleep(SC2355->pwdn_gpio, 1);
997
+
998
+ if (!IS_ERR(SC2355->reset_gpio))
999
+ gpiod_set_value_cansleep(SC2355->reset_gpio, 0);
1000
+
1001
+ /* 8192 cycles prior to first SCCB transaction */
1002
+ delay_us = SC2355_cal_delay(8192);
1003
+ usleep_range(delay_us, delay_us * 2);
10011004
10021005 return 0;
10031006
10041007 disable_clk:
1005
- clk_disable_unprepare(sc2355->xvclk);
1008
+ clk_disable_unprepare(SC2355->xvclk);
10061009
10071010 return ret;
10081011 }
10091012
1010
-static void __sc2355_power_off(struct sc2355 *sc2355)
1013
+static void __SC2355_power_off(struct SC2355 *SC2355)
10111014 {
10121015 int ret;
1013
- struct device *dev = &sc2355->client->dev;
10141016
1015
- if (!IS_ERR(sc2355->pwdn_gpio))
1016
- gpiod_set_value_cansleep(sc2355->pwdn_gpio, 1);
1017
- clk_disable_unprepare(sc2355->xvclk);
1018
- if (!IS_ERR(sc2355->reset_gpio))
1019
- gpiod_set_value_cansleep(sc2355->reset_gpio, 1);
1020
- if (!IS_ERR_OR_NULL(sc2355->pins_sleep)) {
1021
- ret = pinctrl_select_state(sc2355->pinctrl,
1022
- sc2355->pins_sleep);
1017
+ if (!IS_ERR(SC2355->reset_gpio))
1018
+ gpiod_set_value_cansleep(SC2355->reset_gpio, 1);
1019
+
1020
+ if (!IS_ERR(SC2355->pwdn_gpio))
1021
+ gpiod_set_value_cansleep(SC2355->pwdn_gpio, 0);
1022
+ clk_disable_unprepare(SC2355->xvclk);
1023
+ if (!IS_ERR_OR_NULL(SC2355->pins_sleep)) {
1024
+ ret = pinctrl_select_state(SC2355->pinctrl,
1025
+ SC2355->pins_sleep);
10231026 if (ret < 0)
1024
- dev_dbg(dev, "could not set pins\n");
1027
+ dev_dbg(&SC2355->client->dev, "could not set pins\n");
10251028 }
1026
- regulator_bulk_disable(SC2355_NUM_SUPPLIES, sc2355->supplies);
1029
+ regulator_bulk_disable(SC2355_NUM_SUPPLIES, SC2355->supplies);
10271030 }
10281031
1029
-static int sc2355_runtime_resume(struct device *dev)
1032
+static int SC2355_runtime_resume(struct device *dev)
10301033 {
10311034 struct i2c_client *client = to_i2c_client(dev);
10321035 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1033
- struct sc2355 *sc2355 = to_sc2355(sd);
1036
+ struct SC2355 *SC2355 = to_SC2355(sd);
10341037
1035
- return __sc2355_power_on(sc2355);
1038
+ return __SC2355_power_on(SC2355);
10361039 }
10371040
1038
-static int sc2355_runtime_suspend(struct device *dev)
1041
+static int SC2355_runtime_suspend(struct device *dev)
10391042 {
10401043 struct i2c_client *client = to_i2c_client(dev);
10411044 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1042
- struct sc2355 *sc2355 = to_sc2355(sd);
1045
+ struct SC2355 *SC2355 = to_SC2355(sd);
10431046
1044
- __sc2355_power_off(sc2355);
1047
+ __SC2355_power_off(SC2355);
10451048
10461049 return 0;
10471050 }
10481051
10491052 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1050
-static int sc2355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1053
+static int SC2355_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
10511054 {
1052
- struct sc2355 *sc2355 = to_sc2355(sd);
1055
+ struct SC2355 *SC2355 = to_SC2355(sd);
10531056 struct v4l2_mbus_framefmt *try_fmt =
1054
- v4l2_subdev_get_try_format(sd, fh->pad, 0);
1055
- const struct sc2355_mode *def_mode = &supported_modes[0];
1057
+ v4l2_subdev_get_try_format(sd, fh->pad, 0);
1058
+ const struct SC2355_mode *def_mode = &supported_modes[0];
10561059
1057
- mutex_lock(&sc2355->mutex);
1060
+ mutex_lock(&SC2355->mutex);
10581061 /* Initialize try_fmt */
10591062 try_fmt->width = def_mode->width;
10601063 try_fmt->height = def_mode->height;
10611064 try_fmt->code = def_mode->bus_fmt;
10621065 try_fmt->field = V4L2_FIELD_NONE;
10631066
1064
- mutex_unlock(&sc2355->mutex);
1067
+ mutex_unlock(&SC2355->mutex);
10651068 /* No crop or compose */
10661069
10671070 return 0;
10681071 }
10691072 #endif
10701073
1071
-static int sc2355_enum_frame_interval(struct v4l2_subdev *sd,
1072
- struct v4l2_subdev_pad_config *cfg,
1073
- struct v4l2_subdev_frame_interval_enum *fie)
1074
+static int SC2355_enum_frame_interval(struct v4l2_subdev *sd,
1075
+ struct v4l2_subdev_pad_config *cfg,
1076
+ struct v4l2_subdev_frame_interval_enum *fie)
10741077 {
1075
- struct sc2355 *sc2355 = to_sc2355(sd);
1076
-
1077
- if (fie->index >= sc2355->cfg_num)
1078
+ if (fie->index >= ARRAY_SIZE(supported_modes))
10781079 return -EINVAL;
10791080
10801081 fie->code = supported_modes[fie->index].bus_fmt;
10811082 fie->width = supported_modes[fie->index].width;
10821083 fie->height = supported_modes[fie->index].height;
10831084 fie->interval = supported_modes[fie->index].max_fps;
1084
- fie->reserved[0] = supported_modes[fie->index].hdr_mode;
10851085 return 0;
10861086 }
10871087
1088
-static const struct dev_pm_ops sc2355_pm_ops = {
1089
- SET_RUNTIME_PM_OPS(sc2355_runtime_suspend,
1090
- sc2355_runtime_resume, NULL)
1088
+static int SC2355_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
1089
+ struct v4l2_mbus_config *config)
1090
+{
1091
+ u32 val = 0;
1092
+ struct SC2355 *SC2355 = to_SC2355(sd);
1093
+
1094
+ val = 1 << (SC2355->cur_mode->lanes - 1) |
1095
+ V4L2_MBUS_CSI2_CHANNEL_0 |
1096
+ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
1097
+ config->type = V4L2_MBUS_CSI2_DPHY;
1098
+ config->flags = val;
1099
+
1100
+ return 0;
1101
+}
1102
+
1103
+static const struct dev_pm_ops SC2355_pm_ops = {
1104
+ SET_RUNTIME_PM_OPS(SC2355_runtime_suspend,
1105
+ SC2355_runtime_resume, NULL)
10911106 };
10921107
10931108 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1094
-static const struct v4l2_subdev_internal_ops sc2355_internal_ops = {
1095
- .open = sc2355_open,
1109
+static const struct v4l2_subdev_internal_ops SC2355_internal_ops = {
1110
+ .open = SC2355_open,
10961111 };
10971112 #endif
10981113
1099
-static const struct v4l2_subdev_core_ops sc2355_core_ops = {
1100
- .s_power = sc2355_s_power,
1101
- .ioctl = sc2355_ioctl,
1114
+static const struct v4l2_subdev_core_ops SC2355_core_ops = {
1115
+ .s_power = SC2355_s_power,
1116
+ .ioctl = SC2355_ioctl,
11021117 #ifdef CONFIG_COMPAT
1103
- .compat_ioctl32 = sc2355_compat_ioctl32,
1118
+ .compat_ioctl32 = SC2355_compat_ioctl32,
11041119 #endif
11051120 };
11061121
1107
-static const struct v4l2_subdev_video_ops sc2355_video_ops = {
1108
- .s_stream = sc2355_s_stream,
1109
- .g_frame_interval = sc2355_g_frame_interval,
1110
- .g_mbus_config = sc2355_g_mbus_config,
1122
+static const struct v4l2_subdev_video_ops SC2355_video_ops = {
1123
+ .s_stream = SC2355_s_stream,
1124
+ .g_frame_interval = SC2355_g_frame_interval,
11111125 };
11121126
1113
-static const struct v4l2_subdev_pad_ops sc2355_pad_ops = {
1114
- .enum_mbus_code = sc2355_enum_mbus_code,
1115
- .enum_frame_size = sc2355_enum_frame_sizes,
1116
- .enum_frame_interval = sc2355_enum_frame_interval,
1117
- .get_fmt = sc2355_get_fmt,
1118
- .set_fmt = sc2355_set_fmt,
1127
+static const struct v4l2_subdev_pad_ops SC2355_pad_ops = {
1128
+ .enum_mbus_code = SC2355_enum_mbus_code,
1129
+ .enum_frame_size = SC2355_enum_frame_sizes,
1130
+ .enum_frame_interval = SC2355_enum_frame_interval,
1131
+ .get_fmt = SC2355_get_fmt,
1132
+ .set_fmt = SC2355_set_fmt,
1133
+ .get_mbus_config = SC2355_g_mbus_config,
11191134 };
11201135
1121
-static const struct v4l2_subdev_ops sc2355_subdev_ops = {
1122
- .core = &sc2355_core_ops,
1123
- .video = &sc2355_video_ops,
1124
- .pad = &sc2355_pad_ops,
1136
+static const struct v4l2_subdev_ops SC2355_subdev_ops = {
1137
+ .core = &SC2355_core_ops,
1138
+ .video = &SC2355_video_ops,
1139
+ .pad = &SC2355_pad_ops,
11251140 };
11261141
1127
-static int sc2355_set_ctrl(struct v4l2_ctrl *ctrl)
1142
+static void SC2355_modify_fps_info(struct SC2355 *SC2355)
11281143 {
1129
- struct sc2355 *sc2355 = container_of(ctrl->handler,
1130
- struct sc2355, ctrl_handler);
1131
- struct i2c_client *client = sc2355->client;
1144
+ const struct SC2355_mode *mode = SC2355->cur_mode;
1145
+
1146
+ SC2355->cur_fps.denominator = mode->max_fps.denominator * SC2355->cur_vts /
1147
+ mode->vts_def;
1148
+}
1149
+
1150
+static int SC2355_set_ctrl(struct v4l2_ctrl *ctrl)
1151
+{
1152
+ struct SC2355 *SC2355 = container_of(ctrl->handler,
1153
+ struct SC2355, ctrl_handler);
1154
+ struct i2c_client *client = SC2355->client;
11321155 s64 max;
1133
- u32 again, dgain, dgain_fine;
11341156 int ret = 0;
1135
- u32 val;
1157
+#ifndef SLAVE_MODE
1158
+ u16 rising_reg;
1159
+#endif
11361160
11371161 /* Propagate change of current control to all related controls */
11381162 switch (ctrl->id) {
11391163 case V4L2_CID_VBLANK:
11401164 /* Update max exposure while meeting expected vblanking */
1141
- max = sc2355->cur_mode->height + ctrl->val - 4;
1142
- __v4l2_ctrl_modify_range(sc2355->exposure,
1143
- sc2355->exposure->minimum, max,
1144
- sc2355->exposure->step,
1145
- sc2355->exposure->default_value);
1165
+ max = SC2355->cur_mode->height + ctrl->val - 6;
1166
+ __v4l2_ctrl_modify_range(SC2355->exposure,
1167
+ SC2355->exposure->minimum, max,
1168
+ SC2355->exposure->step,
1169
+ SC2355->exposure->default_value);
11461170 break;
11471171 }
1172
+
11481173 if (!pm_runtime_get_if_in_use(&client->dev))
11491174 return 0;
11501175
11511176 switch (ctrl->id) {
11521177 case V4L2_CID_EXPOSURE:
1153
- if (sc2355->cur_mode->hdr_mode != NO_HDR)
1154
- return ret;
1155
- ret = sc2355_write_reg(sc2355->client, SC2355_GROUP_HOLD,
1156
- SC2355_REG_VALUE_08BIT,
1157
- SC2355_GROUP_UPDATE_DATA_START);
1158
- ret |= sc2355_write_reg(sc2355->client, SC2355_REG_EXPOSURE,
1159
- SC2355_REG_VALUE_24BIT, ctrl->val << 4);
1160
- ret |= sc2355_write_reg(sc2355->client, SC2355_GROUP_HOLD,
1161
- SC2355_REG_VALUE_08BIT,
1162
- SC2355_GROUP_UPDATE_LAUNCH);
1178
+ /* 4 least significant bits of expsoure are fractional part */
1179
+ ret = SC2355_write_reg(SC2355->client, SC2355_REG_EXPOSURE,
1180
+ SC2355_REG_VALUE_16BIT, ctrl->val << 4);
1181
+
1182
+#ifndef SLAVE_MODE
1183
+ /* set fsync rising */
1184
+ rising_reg = SC2355_EXP_REG_TO_FSYNC_RISING(ctrl->val);
1185
+ if (rising_reg > 0xff) {
1186
+ rising_reg = 0xff;
1187
+ dev_warn(&client->dev,
1188
+ "error: rising reg exceed max val 0xff.\n");
1189
+ }
1190
+
1191
+ dev_info(&client->dev, "rising: reg:%d\n", rising_reg);
1192
+
1193
+ ret |= SC2355_write_reg(SC2355->client, SC2355_FSYNC_RISING_REG,
1194
+ SC2355_REG_VALUE_08BIT, rising_reg);
1195
+#endif
1196
+
11631197 break;
1164
-
11651198 case V4L2_CID_ANALOGUE_GAIN:
1166
- if (sc2355->cur_mode->hdr_mode != NO_HDR)
1167
- return ret;
1168
- sc2355_get_gain(ctrl->val, &again, &dgain, &dgain_fine);
1169
-
1170
- val = ctrl->val << 1;
1171
-
1172
- dev_dbg(&client->dev, "recv:%d set again 0x%x, set dgain 0x%x, dgain_fine 0x%x\n",
1173
- ctrl->val, again, dgain, dgain_fine);
1174
-
1175
- ret |= sc2355_write_reg(sc2355->client,
1176
- SC2355_REG_AGAIN,
1177
- SC2355_REG_VALUE_08BIT,
1178
- again);
1179
- ret |= sc2355_write_reg(sc2355->client,
1180
- SC2355_REG_DGAIN,
1181
- SC2355_REG_VALUE_08BIT,
1182
- dgain);
1183
- ret |= sc2355_write_reg(sc2355->client,
1184
- SC2355_REG_DGAIN_FINE,
1185
- SC2355_REG_VALUE_08BIT,
1186
- dgain_fine);
1199
+ ret = SC2355_set_ctrl_gain(SC2355, ctrl->val);
11871200 break;
11881201 case V4L2_CID_VBLANK:
1189
- ret = sc2355_write_reg(sc2355->client, SC2355_REG_VTS,
1202
+ ret = SC2355_write_reg(SC2355->client, SC2355_REG_VTS,
11901203 SC2355_REG_VALUE_16BIT,
1191
- ctrl->val + sc2355->cur_mode->height);
1192
- dev_dbg(&client->dev, "set vblank 0x%x\n",
1193
- ctrl->val);
1204
+ ctrl->val + SC2355->cur_mode->height);
1205
+ if (!ret)
1206
+ SC2355->cur_vts = ctrl->val + SC2355->cur_mode->height;
1207
+ if (SC2355->cur_vts != SC2355->cur_mode->vts_def)
1208
+ SC2355_modify_fps_info(SC2355);
11941209 break;
11951210 case V4L2_CID_TEST_PATTERN:
1196
- ret = sc2355_enable_test_pattern(sc2355, ctrl->val);
1197
- break;
1198
- case V4L2_CID_HFLIP:
1199
- ret = sc2355_read_reg(sc2355->client, SC2355_FLIP_REG,
1200
- SC2355_REG_VALUE_08BIT, &val);
1201
- if (ret)
1202
- break;
1203
- if (ctrl->val)
1204
- val |= SC2355_MIRROR_MASK;
1205
- else
1206
- val &= ~SC2355_MIRROR_MASK;
1207
- ret |= sc2355_write_reg(sc2355->client, SC2355_FLIP_REG,
1208
- SC2355_REG_VALUE_08BIT, val);
1209
- break;
1210
- case V4L2_CID_VFLIP:
1211
- ret = sc2355_read_reg(sc2355->client, SC2355_FLIP_REG,
1212
- SC2355_REG_VALUE_08BIT, &val);
1213
- if (ret)
1214
- break;
1215
- if (ctrl->val)
1216
- val |= SC2355_FLIP_MASK;
1217
- else
1218
- val &= ~SC2355_FLIP_MASK;
1219
- ret |= sc2355_write_reg(sc2355->client, SC2355_FLIP_REG,
1220
- SC2355_REG_VALUE_08BIT, val);
1211
+ ret = SC2355_enable_test_pattern(SC2355, ctrl->val);
12211212 break;
12221213 default:
12231214 dev_warn(&client->dev, "%s Unhandled id:0x%x, val:0x%x\n",
....@@ -1230,78 +1221,75 @@
12301221 return ret;
12311222 }
12321223
1233
-static const struct v4l2_ctrl_ops sc2355_ctrl_ops = {
1234
- .s_ctrl = sc2355_set_ctrl,
1224
+static const struct v4l2_ctrl_ops SC2355_ctrl_ops = {
1225
+ .s_ctrl = SC2355_set_ctrl,
12351226 };
12361227
1237
-static int sc2355_initialize_controls(struct sc2355 *sc2355)
1228
+static int SC2355_initialize_controls(struct SC2355 *SC2355)
12381229 {
1239
- const struct sc2355_mode *mode;
1230
+ const struct SC2355_mode *mode;
12401231 struct v4l2_ctrl_handler *handler;
12411232 s64 exposure_max, vblank_def;
12421233 u32 h_blank;
12431234 int ret;
1244
- u64 pixel_rate = 0;
12451235
1246
- handler = &sc2355->ctrl_handler;
1247
- mode = sc2355->cur_mode;
1248
- ret = v4l2_ctrl_handler_init(handler, 9);
1236
+ handler = &SC2355->ctrl_handler;
1237
+ mode = SC2355->cur_mode;
1238
+ ret = v4l2_ctrl_handler_init(handler, 8);
12491239 if (ret)
12501240 return ret;
1251
- handler->lock = &sc2355->mutex;
1241
+ handler->lock = &SC2355->mutex;
12521242
1253
- sc2355->link_freq = v4l2_ctrl_new_int_menu(handler, NULL,
1254
- V4L2_CID_LINK_FREQ,
1255
- ARRAY_SIZE(link_freq_items) - 1, 0,
1256
- link_freq_items);
1257
- __v4l2_ctrl_s_ctrl(sc2355->link_freq, mode->mipi_freq_idx);
1243
+ SC2355->link_freq = v4l2_ctrl_new_int_menu(handler,
1244
+ NULL, V4L2_CID_LINK_FREQ,
1245
+ ARRAY_SIZE(link_freq_menu_items) - 1, 0,
1246
+ link_freq_menu_items);
12581247
1259
- /* pixel rate = link frequency * 2 * lanes / BITS_PER_SAMPLE */
1260
- pixel_rate = (u32)link_freq_items[mode->mipi_freq_idx] / mode->bpp * 2 * SC2355_LANES;
1261
- sc2355->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
1262
- V4L2_CID_PIXEL_RATE, 0, SC2355_MAX_PIXEL_RATE,
1263
- 1, pixel_rate);
1248
+ SC2355->pixel_rate = v4l2_ctrl_new_std(handler, NULL,
1249
+ V4L2_CID_PIXEL_RATE,
1250
+ 0, PIXEL_RATE_WITH_360M,
1251
+ 1, mode->pixel_rate);
1252
+
1253
+ __v4l2_ctrl_s_ctrl(SC2355->link_freq, mode->pixel_rate);
12641254
12651255 h_blank = mode->hts_def - mode->width;
1266
- sc2355->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
1267
- h_blank, h_blank, 1, h_blank);
1268
- if (sc2355->hblank)
1269
- sc2355->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
1256
+ SC2355->hblank = v4l2_ctrl_new_std(handler, NULL, V4L2_CID_HBLANK,
1257
+ h_blank, h_blank, 1, h_blank);
1258
+ if (SC2355->hblank)
1259
+ SC2355->hblank->flags |= V4L2_CTRL_FLAG_READ_ONLY;
12701260
12711261 vblank_def = mode->vts_def - mode->height;
1272
- sc2355->vblank = v4l2_ctrl_new_std(handler, &sc2355_ctrl_ops,
1273
- V4L2_CID_VBLANK, vblank_def,
1274
- SC2355_VTS_MAX - mode->height,
1275
- 1, vblank_def);
1262
+ SC2355->cur_vts = mode->vts_def;
1263
+ SC2355->cur_fps = mode->max_fps;
1264
+ SC2355->vblank = v4l2_ctrl_new_std(handler, &SC2355_ctrl_ops,
1265
+ V4L2_CID_VBLANK, vblank_def,
1266
+ SC2355_VTS_MAX - mode->height,
1267
+ 1, vblank_def);
12761268
1277
- exposure_max = mode->vts_def - 3;
1278
- sc2355->exposure = v4l2_ctrl_new_std(handler, &sc2355_ctrl_ops,
1279
- V4L2_CID_EXPOSURE, SC2355_EXPOSURE_MIN,
1280
- exposure_max, SC2355_EXPOSURE_STEP,
1281
- mode->exp_def);
1269
+ exposure_max = mode->vts_def - 6;
1270
+ SC2355->exposure = v4l2_ctrl_new_std(handler, &SC2355_ctrl_ops,
1271
+ V4L2_CID_EXPOSURE, SC2355_EXPOSURE_MIN,
1272
+ exposure_max, SC2355_EXPOSURE_STEP,
1273
+ mode->exp_def);
12821274
1283
- sc2355->anal_gain = v4l2_ctrl_new_std(handler, &sc2355_ctrl_ops,
1284
- V4L2_CID_ANALOGUE_GAIN, SC2355_GAIN_MIN,
1285
- SC2355_GAIN_MAX, SC2355_GAIN_STEP,
1286
- SC2355_GAIN_DEFAULT);
1275
+ SC2355->anal_gain = v4l2_ctrl_new_std(handler, &SC2355_ctrl_ops,
1276
+ V4L2_CID_ANALOGUE_GAIN, ANALOG_GAIN_MIN,
1277
+ ANALOG_GAIN_MAX, ANALOG_GAIN_STEP,
1278
+ ANALOG_GAIN_DEFAULT);
12871279
1288
- sc2355->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
1289
- &sc2355_ctrl_ops, V4L2_CID_TEST_PATTERN,
1290
- ARRAY_SIZE(sc2355_test_pattern_menu) - 1,
1291
- 0, 0, sc2355_test_pattern_menu);
1292
-
1293
- v4l2_ctrl_new_std(handler, &sc2355_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
1294
- v4l2_ctrl_new_std(handler, &sc2355_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
1280
+ SC2355->test_pattern = v4l2_ctrl_new_std_menu_items(handler,
1281
+ &SC2355_ctrl_ops, V4L2_CID_TEST_PATTERN,
1282
+ ARRAY_SIZE(SC2355_test_pattern_menu) - 1,
1283
+ 0, 0, SC2355_test_pattern_menu);
12951284
12961285 if (handler->error) {
12971286 ret = handler->error;
1298
- dev_err(&sc2355->client->dev,
1287
+ dev_err(&SC2355->client->dev,
12991288 "Failed to init controls(%d)\n", ret);
13001289 goto err_free_handler;
13011290 }
13021291
1303
- sc2355->subdev.ctrl_handler = handler;
1304
- sc2355->has_init_exp = false;
1292
+ SC2355->subdev.ctrl_handler = handler;
13051293
13061294 return 0;
13071295
....@@ -1311,162 +1299,141 @@
13111299 return ret;
13121300 }
13131301
1314
-static int sc2355_check_sensor_id(struct sc2355 *sc2355,
1315
- struct i2c_client *client)
1302
+static int SC2355_check_sensor_id(struct SC2355 *SC2355,
1303
+ struct i2c_client *client)
13161304 {
1317
- struct device *dev = &sc2355->client->dev;
1305
+ struct device *dev = &SC2355->client->dev;
13181306 u32 id = 0;
13191307 int ret;
13201308
1321
-
1322
- ret = sc2355_read_reg(client, SC2355_REG_CHIP_ID,
1323
- SC2355_REG_VALUE_16BIT, &id);
1324
- if (id != CHIP_ID) {
1309
+ ret = SC2355_read_reg(client, SC2355_REG_CHIP_ID,
1310
+ SC2355_REG_VALUE_16BIT, &id);
1311
+ if (ret || id != CHIP_ID) {
13251312 dev_err(dev, "Unexpected sensor id(%04x), ret(%d)\n", id, ret);
13261313 return -ENODEV;
13271314 }
13281315
1329
- dev_info(dev, "Detected SC%04x sensor\n", CHIP_ID);
1316
+ dev_info(dev, "Detected SC2355 CHIP ID = 0x%04x sensor\n", CHIP_ID);
13301317
13311318 return 0;
13321319 }
13331320
1334
-static int sc2355_configure_regulators(struct sc2355 *sc2355)
1321
+static int SC2355_configure_regulators(struct SC2355 *SC2355)
13351322 {
13361323 unsigned int i;
13371324
13381325 for (i = 0; i < SC2355_NUM_SUPPLIES; i++)
1339
- sc2355->supplies[i].supply = sc2355_supply_names[i];
1326
+ SC2355->supplies[i].supply = SC2355_supply_names[i];
13401327
1341
- return devm_regulator_bulk_get(&sc2355->client->dev,
1328
+ return devm_regulator_bulk_get(&SC2355->client->dev,
13421329 SC2355_NUM_SUPPLIES,
1343
- sc2355->supplies);
1330
+ SC2355->supplies);
13441331 }
13451332
1346
-static int sc2355_probe(struct i2c_client *client,
1347
- const struct i2c_device_id *id)
1333
+static int SC2355_probe(struct i2c_client *client,
1334
+ const struct i2c_device_id *id)
13481335 {
13491336 struct device *dev = &client->dev;
13501337 struct device_node *node = dev->of_node;
1351
- struct sc2355 *sc2355;
1338
+ struct SC2355 *SC2355;
13521339 struct v4l2_subdev *sd;
13531340 char facing[2];
13541341 int ret;
1355
- u32 i, hdr_mode = 0;
13561342
13571343 dev_info(dev, "driver version: %02x.%02x.%02x",
13581344 DRIVER_VERSION >> 16,
13591345 (DRIVER_VERSION & 0xff00) >> 8,
13601346 DRIVER_VERSION & 0x00ff);
13611347
1362
- sc2355 = devm_kzalloc(dev, sizeof(*sc2355), GFP_KERNEL);
1363
- if (!sc2355)
1348
+ SC2355 = devm_kzalloc(dev, sizeof(*SC2355), GFP_KERNEL);
1349
+ if (!SC2355)
13641350 return -ENOMEM;
13651351
13661352 ret = of_property_read_u32(node, RKMODULE_CAMERA_MODULE_INDEX,
1367
- &sc2355->module_index);
1353
+ &SC2355->module_index);
13681354 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_FACING,
1369
- &sc2355->module_facing);
1355
+ &SC2355->module_facing);
13701356 ret |= of_property_read_string(node, RKMODULE_CAMERA_MODULE_NAME,
1371
- &sc2355->module_name);
1357
+ &SC2355->module_name);
13721358 ret |= of_property_read_string(node, RKMODULE_CAMERA_LENS_NAME,
1373
- &sc2355->len_name);
1359
+ &SC2355->len_name);
13741360 if (ret) {
13751361 dev_err(dev, "could not get module information!\n");
13761362 return -EINVAL;
13771363 }
1364
+ SC2355->client = client;
1365
+ SC2355->cur_mode = &supported_modes[0];
13781366
1379
- ret = of_property_read_u32(node, OF_CAMERA_HDR_MODE,
1380
- &hdr_mode);
1381
-
1382
- if (ret) {
1383
- hdr_mode = NO_HDR;
1384
- dev_warn(dev, " Get hdr mode failed! no hdr default\n");
1385
- }
1386
-
1387
- sc2355->cfg_num = ARRAY_SIZE(supported_modes);
1388
- for (i = 0; i < sc2355->cfg_num; i++) {
1389
- if (hdr_mode == supported_modes[i].hdr_mode) {
1390
- sc2355->cur_mode = &supported_modes[i];
1391
- break;
1392
- }
1393
- }
1394
- sc2355->client = client;
1395
-
1396
- sc2355->xvclk = devm_clk_get(dev, "xvclk");
1397
- if (IS_ERR(sc2355->xvclk)) {
1367
+ SC2355->xvclk = devm_clk_get(dev, "xvclk");
1368
+ if (IS_ERR(SC2355->xvclk)) {
13981369 dev_err(dev, "Failed to get xvclk\n");
13991370 return -EINVAL;
14001371 }
14011372
1402
- sc2355->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
1403
- if (IS_ERR(sc2355->reset_gpio))
1373
+ SC2355->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
1374
+ if (IS_ERR(SC2355->reset_gpio))
14041375 dev_warn(dev, "Failed to get reset-gpios\n");
14051376
1406
- sc2355->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
1407
- if (IS_ERR(sc2355->pwdn_gpio))
1377
+ SC2355->pwdn_gpio = devm_gpiod_get(dev, "pwdn", GPIOD_OUT_LOW);
1378
+ if (IS_ERR(SC2355->pwdn_gpio))
14081379 dev_warn(dev, "Failed to get pwdn-gpios\n");
1409
-
1410
- sc2355->pinctrl = devm_pinctrl_get(dev);
1411
- if (!IS_ERR(sc2355->pinctrl)) {
1412
- sc2355->pins_default =
1413
- pinctrl_lookup_state(sc2355->pinctrl,
1414
- OF_CAMERA_PINCTRL_STATE_DEFAULT);
1415
- if (IS_ERR(sc2355->pins_default))
1416
- dev_err(dev, "could not get default pinstate\n");
1417
-
1418
- sc2355->pins_sleep =
1419
- pinctrl_lookup_state(sc2355->pinctrl,
1420
- OF_CAMERA_PINCTRL_STATE_SLEEP);
1421
- if (IS_ERR(sc2355->pins_sleep))
1422
- dev_err(dev, "could not get sleep pinstate\n");
1423
- } else {
1424
- dev_err(dev, "no pinctrl\n");
1425
- }
1426
-
1427
- ret = sc2355_configure_regulators(sc2355);
1380
+ ret = SC2355_configure_regulators(SC2355);
14281381 if (ret) {
14291382 dev_err(dev, "Failed to get power regulators\n");
14301383 return ret;
14311384 }
14321385
1433
- mutex_init(&sc2355->mutex);
1386
+ SC2355->pinctrl = devm_pinctrl_get(dev);
1387
+ if (!IS_ERR(SC2355->pinctrl)) {
1388
+ SC2355->pins_default =
1389
+ pinctrl_lookup_state(SC2355->pinctrl,
1390
+ OF_CAMERA_PINCTRL_STATE_DEFAULT);
1391
+ if (IS_ERR(SC2355->pins_default))
1392
+ dev_err(dev, "could not get default pinstate\n");
14341393
1435
- sd = &sc2355->subdev;
1436
- v4l2_i2c_subdev_init(sd, client, &sc2355_subdev_ops);
1437
- ret = sc2355_initialize_controls(sc2355);
1394
+ SC2355->pins_sleep =
1395
+ pinctrl_lookup_state(SC2355->pinctrl,
1396
+ OF_CAMERA_PINCTRL_STATE_SLEEP);
1397
+ if (IS_ERR(SC2355->pins_sleep))
1398
+ dev_err(dev, "could not get sleep pinstate\n");
1399
+ }
1400
+ mutex_init(&SC2355->mutex);
1401
+
1402
+ sd = &SC2355->subdev;
1403
+ v4l2_i2c_subdev_init(sd, client, &SC2355_subdev_ops);
1404
+ ret = SC2355_initialize_controls(SC2355);
14381405 if (ret)
14391406 goto err_destroy_mutex;
14401407
1441
- ret = __sc2355_power_on(sc2355);
1408
+ ret = __SC2355_power_on(SC2355);
14421409 if (ret)
14431410 goto err_free_handler;
14441411
1445
- ret = sc2355_check_sensor_id(sc2355, client);
1412
+ ret = SC2355_check_sensor_id(SC2355, client);
14461413 if (ret)
14471414 goto err_power_off;
14481415
14491416 #ifdef CONFIG_VIDEO_V4L2_SUBDEV_API
1450
- sd->internal_ops = &sc2355_internal_ops;
1451
- sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1417
+ sd->internal_ops = &SC2355_internal_ops;
1418
+ sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE |
1419
+ V4L2_SUBDEV_FL_HAS_EVENTS;
14521420 #endif
1453
-
14541421 #if defined(CONFIG_MEDIA_CONTROLLER)
1455
- sc2355->pad.flags = MEDIA_PAD_FL_SOURCE;
1422
+ SC2355->pad.flags = MEDIA_PAD_FL_SOURCE;
14561423 sd->entity.function = MEDIA_ENT_F_CAM_SENSOR;
1457
- ret = media_entity_pads_init(&sd->entity, 1, &sc2355->pad);
1424
+ ret = media_entity_pads_init(&sd->entity, 1, &SC2355->pad);
14581425 if (ret < 0)
14591426 goto err_power_off;
14601427 #endif
14611428
14621429 memset(facing, 0, sizeof(facing));
1463
- if (strcmp(sc2355->module_facing, "back") == 0)
1430
+ if (strcmp(SC2355->module_facing, "back") == 0)
14641431 facing[0] = 'b';
14651432 else
14661433 facing[0] = 'f';
14671434
14681435 snprintf(sd->name, sizeof(sd->name), "m%02d_%s_%s %s",
1469
- sc2355->module_index, facing,
1436
+ SC2355->module_index, facing,
14701437 SC2355_NAME, dev_name(sd->dev));
14711438 ret = v4l2_async_register_subdev_sensor_common(sd);
14721439 if (ret) {
....@@ -1477,9 +1444,7 @@
14771444 pm_runtime_set_active(dev);
14781445 pm_runtime_enable(dev);
14791446 pm_runtime_idle(dev);
1480
-#ifdef USED_SYS_DEBUG
1481
- add_sysfs_interfaces(dev);
1482
-#endif
1447
+
14831448 return 0;
14841449
14851450 err_clean_entity:
....@@ -1487,75 +1452,71 @@
14871452 media_entity_cleanup(&sd->entity);
14881453 #endif
14891454 err_power_off:
1490
- __sc2355_power_off(sc2355);
1455
+ __SC2355_power_off(SC2355);
14911456 err_free_handler:
1492
- v4l2_ctrl_handler_free(&sc2355->ctrl_handler);
1457
+ v4l2_ctrl_handler_free(&SC2355->ctrl_handler);
14931458 err_destroy_mutex:
1494
- mutex_destroy(&sc2355->mutex);
1459
+ mutex_destroy(&SC2355->mutex);
14951460
14961461 return ret;
14971462 }
14981463
1499
-static int sc2355_remove(struct i2c_client *client)
1464
+static int SC2355_remove(struct i2c_client *client)
15001465 {
15011466 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1502
- struct sc2355 *sc2355 = to_sc2355(sd);
1467
+ struct SC2355 *SC2355 = to_SC2355(sd);
15031468
15041469 v4l2_async_unregister_subdev(sd);
15051470 #if defined(CONFIG_MEDIA_CONTROLLER)
15061471 media_entity_cleanup(&sd->entity);
15071472 #endif
1508
- v4l2_ctrl_handler_free(&sc2355->ctrl_handler);
1509
- mutex_destroy(&sc2355->mutex);
1473
+ v4l2_ctrl_handler_free(&SC2355->ctrl_handler);
1474
+ mutex_destroy(&SC2355->mutex);
15101475
15111476 pm_runtime_disable(&client->dev);
15121477 if (!pm_runtime_status_suspended(&client->dev))
1513
- __sc2355_power_off(sc2355);
1478
+ __SC2355_power_off(SC2355);
15141479 pm_runtime_set_suspended(&client->dev);
15151480
15161481 return 0;
15171482 }
15181483
15191484 #if IS_ENABLED(CONFIG_OF)
1520
-static const struct of_device_id sc2355_of_match[] = {
1485
+static const struct of_device_id SC2355_of_match[] = {
15211486 { .compatible = "smartsens,sc2355" },
1522
- { },
1487
+ {},
15231488 };
1524
-MODULE_DEVICE_TABLE(of, sc2355_of_match);
1489
+MODULE_DEVICE_TABLE(of, SC2355_of_match);
15251490 #endif
15261491
1527
-static const struct i2c_device_id sc2355_match_id[] = {
1492
+static const struct i2c_device_id SC2355_match_id[] = {
15281493 { "smartsens,sc2355", 0 },
15291494 { },
15301495 };
15311496
1532
-static struct i2c_driver sc2355_i2c_driver = {
1497
+static struct i2c_driver SC2355_i2c_driver = {
15331498 .driver = {
15341499 .name = SC2355_NAME,
1535
- .pm = &sc2355_pm_ops,
1536
- .of_match_table = of_match_ptr(sc2355_of_match),
1500
+ .pm = &SC2355_pm_ops,
1501
+ .of_match_table = of_match_ptr(SC2355_of_match),
15371502 },
1538
- .probe = &sc2355_probe,
1539
- .remove = &sc2355_remove,
1540
- .id_table = sc2355_match_id,
1503
+ .probe = &SC2355_probe,
1504
+ .remove = &SC2355_remove,
1505
+ .id_table = SC2355_match_id,
15411506 };
15421507
1543
-#ifdef CONFIG_ROCKCHIP_THUNDER_BOOT
1544
-module_i2c_driver(sc2355_i2c_driver);
1545
-#else
15461508 static int __init sensor_mod_init(void)
15471509 {
1548
- return i2c_add_driver(&sc2355_i2c_driver);
1510
+ return i2c_add_driver(&SC2355_i2c_driver);
15491511 }
15501512
15511513 static void __exit sensor_mod_exit(void)
15521514 {
1553
- i2c_del_driver(&sc2355_i2c_driver);
1515
+ i2c_del_driver(&SC2355_i2c_driver);
15541516 }
15551517
15561518 device_initcall_sync(sensor_mod_init);
15571519 module_exit(sensor_mod_exit);
1558
-#endif
15591520
1560
-MODULE_DESCRIPTION("Smartsens sc2355 sensor driver");
1561
-MODULE_LICENSE("GPL v2");
1521
+MODULE_DESCRIPTION("Smartsens SC2355 sensor driver");
1522
+MODULE_LICENSE("GPL");