forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
kernel/drivers/media/platform/rockchip/cif/subdev-itf.c
....@@ -20,10 +20,61 @@
2020 #include <media/videobuf2-dma-contig.h>
2121 #include <media/v4l2-fwnode.h>
2222 #include "dev.h"
23
+#include <linux/regulator/consumer.h>
24
+#include <linux/rk-camera-module.h>
25
+#include "common.h"
2326
2427 static inline struct sditf_priv *to_sditf_priv(struct v4l2_subdev *subdev)
2528 {
2629 return container_of(subdev, struct sditf_priv, sd);
30
+}
31
+
32
+static void sditf_buffree_work(struct work_struct *work)
33
+{
34
+ struct sditf_work_struct *buffree_work = container_of(work,
35
+ struct sditf_work_struct,
36
+ work);
37
+ struct sditf_priv *priv = container_of(buffree_work,
38
+ struct sditf_priv,
39
+ buffree_work);
40
+ struct rkcif_rx_buffer *rx_buf = NULL;
41
+ unsigned long flags;
42
+ LIST_HEAD(local_list);
43
+
44
+ spin_lock_irqsave(&priv->cif_dev->buffree_lock, flags);
45
+ list_replace_init(&priv->buf_free_list, &local_list);
46
+ while (!list_empty(&local_list)) {
47
+ rx_buf = list_first_entry(&local_list,
48
+ struct rkcif_rx_buffer, list_free);
49
+ if (rx_buf) {
50
+ list_del(&rx_buf->list_free);
51
+ rkcif_free_reserved_mem_buf(priv->cif_dev, rx_buf);
52
+ }
53
+ }
54
+ spin_unlock_irqrestore(&priv->cif_dev->buffree_lock, flags);
55
+}
56
+
57
+static void sditf_get_hdr_mode(struct sditf_priv *priv)
58
+{
59
+ struct rkcif_device *cif_dev = priv->cif_dev;
60
+ struct rkmodule_hdr_cfg hdr_cfg;
61
+ int ret = 0;
62
+
63
+ if (!cif_dev->terminal_sensor.sd)
64
+ rkcif_update_sensor_info(&cif_dev->stream[0]);
65
+
66
+ if (cif_dev->terminal_sensor.sd) {
67
+ ret = v4l2_subdev_call(cif_dev->terminal_sensor.sd,
68
+ core, ioctl,
69
+ RKMODULE_GET_HDR_CFG,
70
+ &hdr_cfg);
71
+ if (!ret)
72
+ priv->hdr_cfg = hdr_cfg;
73
+ else
74
+ priv->hdr_cfg.hdr_mode = NO_HDR;
75
+ } else {
76
+ priv->hdr_cfg.hdr_mode = NO_HDR;
77
+ }
2778 }
2879
2980 static int sditf_g_frame_interval(struct v4l2_subdev *sd,
....@@ -44,7 +95,7 @@
4495 return -EINVAL;
4596 }
4697
47
-static int sditf_g_mbus_config(struct v4l2_subdev *sd,
98
+static int sditf_g_mbus_config(struct v4l2_subdev *sd, unsigned int pad_id,
4899 struct v4l2_mbus_config *config)
49100 {
50101 struct sditf_priv *priv = to_sditf_priv(sd);
....@@ -56,7 +107,12 @@
56107
57108 if (cif_dev->active_sensor) {
58109 sensor_sd = cif_dev->active_sensor->sd;
59
- return v4l2_subdev_call(sensor_sd, video, g_mbus_config, config);
110
+ return v4l2_subdev_call(sensor_sd, pad, get_mbus_config, 0, config);
111
+ } else {
112
+ config->type = V4L2_MBUS_CSI2_DPHY;
113
+ config->flags = V4L2_MBUS_CSI2_CHANNEL_0 |
114
+ V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
115
+ return 0;
60116 }
61117
62118 return -EINVAL;
....@@ -69,12 +125,18 @@
69125 struct sditf_priv *priv = to_sditf_priv(sd);
70126 struct rkcif_device *cif_dev = priv->cif_dev;
71127 struct v4l2_subdev_selection input_sel;
128
+ struct v4l2_pix_format_mplane pixm;
129
+ const struct cif_output_fmt *out_fmt;
72130 int ret = -EINVAL;
131
+ bool is_uncompact = false;
73132
74133 if (!cif_dev->terminal_sensor.sd)
75134 rkcif_update_sensor_info(&cif_dev->stream[0]);
76135
77136 if (cif_dev->terminal_sensor.sd) {
137
+ sditf_get_hdr_mode(priv);
138
+ fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
139
+ fmt->pad = 0;
78140 ret = v4l2_subdev_call(cif_dev->terminal_sensor.sd, pad, get_fmt, NULL, fmt);
79141 if (ret) {
80142 v4l2_err(&priv->sd,
....@@ -83,6 +145,8 @@
83145 }
84146
85147 input_sel.target = V4L2_SEL_TGT_CROP_BOUNDS;
148
+ input_sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
149
+ input_sel.pad = 0;
86150 ret = v4l2_subdev_call(cif_dev->terminal_sensor.sd,
87151 pad, get_selection, NULL,
88152 &input_sel);
....@@ -90,9 +154,150 @@
90154 fmt->format.width = input_sel.r.width;
91155 fmt->format.height = input_sel.r.height;
92156 }
157
+ priv->cap_info.width = fmt->format.width;
158
+ priv->cap_info.height = fmt->format.height;
159
+ pixm.pixelformat = rkcif_mbus_pixelcode_to_v4l2(fmt->format.code);
160
+ pixm.width = priv->cap_info.width;
161
+ pixm.height = priv->cap_info.height;
162
+
163
+ out_fmt = rkcif_find_output_fmt(NULL, pixm.pixelformat);
164
+ if (priv->toisp_inf.link_mode == TOISP_UNITE &&
165
+ ((pixm.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL) * out_fmt->raw_bpp / 8) & 0xf)
166
+ is_uncompact = true;
167
+
168
+ v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
169
+ "%s, width %d, height %d, hdr mode %d\n",
170
+ __func__, fmt->format.width, fmt->format.height, priv->hdr_cfg.hdr_mode);
171
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
172
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
173
+ rkcif_set_fmt(&cif_dev->stream[0], &pixm, false);
174
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
175
+ if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE &&
176
+ priv->toisp_inf.link_mode == TOISP_UNITE) {
177
+ if (is_uncompact) {
178
+ cif_dev->stream[0].is_compact = false;
179
+ cif_dev->stream[0].is_high_align = true;
180
+ } else {
181
+ cif_dev->stream[0].is_compact = true;
182
+ }
183
+ }
184
+ rkcif_set_fmt(&cif_dev->stream[0], &pixm, false);
185
+ rkcif_set_fmt(&cif_dev->stream[1], &pixm, false);
186
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
187
+ if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE &&
188
+ priv->toisp_inf.link_mode == TOISP_UNITE) {
189
+ if (is_uncompact) {
190
+ cif_dev->stream[0].is_compact = false;
191
+ cif_dev->stream[0].is_high_align = true;
192
+ cif_dev->stream[1].is_compact = false;
193
+ cif_dev->stream[1].is_high_align = true;
194
+ } else {
195
+ cif_dev->stream[0].is_compact = true;
196
+ cif_dev->stream[1].is_compact = true;
197
+ }
198
+ }
199
+ rkcif_set_fmt(&cif_dev->stream[0], &pixm, false);
200
+ rkcif_set_fmt(&cif_dev->stream[1], &pixm, false);
201
+ rkcif_set_fmt(&cif_dev->stream[2], &pixm, false);
202
+ }
203
+ } else {
204
+ if (priv->sensor_sd) {
205
+ fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
206
+ fmt->pad = 0;
207
+ ret = v4l2_subdev_call(priv->sensor_sd, pad, get_fmt, NULL, fmt);
208
+ if (ret) {
209
+ v4l2_err(&priv->sd,
210
+ "%s: get sensor format failed\n", __func__);
211
+ return ret;
212
+ }
213
+
214
+ input_sel.target = V4L2_SEL_TGT_CROP_BOUNDS;
215
+ input_sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
216
+ input_sel.pad = 0;
217
+ ret = v4l2_subdev_call(priv->sensor_sd,
218
+ pad, get_selection, NULL,
219
+ &input_sel);
220
+ if (!ret) {
221
+ fmt->format.width = input_sel.r.width;
222
+ fmt->format.height = input_sel.r.height;
223
+ }
224
+ priv->cap_info.width = fmt->format.width;
225
+ priv->cap_info.height = fmt->format.height;
226
+ pixm.pixelformat = rkcif_mbus_pixelcode_to_v4l2(fmt->format.code);
227
+ pixm.width = priv->cap_info.width;
228
+ pixm.height = priv->cap_info.height;
229
+ } else {
230
+ fmt->which = V4L2_SUBDEV_FORMAT_ACTIVE;
231
+ fmt->pad = 0;
232
+ fmt->format.code = MEDIA_BUS_FMT_SBGGR10_1X10;
233
+ fmt->format.width = 640;
234
+ fmt->format.height = 480;
235
+ }
93236 }
94237
95238 return 0;
239
+}
240
+
241
+static int sditf_init_buf(struct sditf_priv *priv)
242
+{
243
+ struct rkcif_device *cif_dev = priv->cif_dev;
244
+ int ret = 0;
245
+
246
+ if (priv->hdr_cfg.hdr_mode == HDR_X2) {
247
+ if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) {
248
+ if (cif_dev->is_thunderboot)
249
+ cif_dev->resmem_size /= 2;
250
+ ret = rkcif_init_rx_buf(&cif_dev->stream[0], priv->buf_num);
251
+ if (cif_dev->is_thunderboot)
252
+ cif_dev->resmem_pa += cif_dev->resmem_size;
253
+ ret |= rkcif_init_rx_buf(&cif_dev->stream[1], priv->buf_num);
254
+ } else {
255
+ ret = rkcif_init_rx_buf(&cif_dev->stream[0], priv->buf_num);
256
+ }
257
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
258
+ if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) {
259
+ if (cif_dev->is_thunderboot)
260
+ cif_dev->resmem_size /= 3;
261
+ ret = rkcif_init_rx_buf(&cif_dev->stream[0], priv->buf_num);
262
+ if (cif_dev->is_thunderboot)
263
+ cif_dev->resmem_pa += cif_dev->resmem_size;
264
+ ret |= rkcif_init_rx_buf(&cif_dev->stream[1], priv->buf_num);
265
+ if (cif_dev->is_thunderboot)
266
+ cif_dev->resmem_pa += cif_dev->resmem_size;
267
+ ret |= rkcif_init_rx_buf(&cif_dev->stream[2], priv->buf_num);
268
+ } else {
269
+ ret = rkcif_init_rx_buf(&cif_dev->stream[0], priv->buf_num);
270
+ ret |= rkcif_init_rx_buf(&cif_dev->stream[1], priv->buf_num);
271
+ }
272
+ } else {
273
+ if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO)
274
+ ret = rkcif_init_rx_buf(&cif_dev->stream[0], priv->buf_num);
275
+ else
276
+ ret = -EINVAL;
277
+ }
278
+ return ret;
279
+}
280
+
281
+static void sditf_free_buf(struct sditf_priv *priv)
282
+{
283
+ struct rkcif_device *cif_dev = priv->cif_dev;
284
+
285
+ if (priv->hdr_cfg.hdr_mode == HDR_X2) {
286
+ rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
287
+ rkcif_free_rx_buf(&cif_dev->stream[1], priv->buf_num);
288
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
289
+ rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
290
+ rkcif_free_rx_buf(&cif_dev->stream[1], priv->buf_num);
291
+ rkcif_free_rx_buf(&cif_dev->stream[2], priv->buf_num);
292
+ } else {
293
+ rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
294
+ }
295
+ if (cif_dev->is_thunderboot) {
296
+ cif_dev->wait_line_cache = 0;
297
+ cif_dev->wait_line = 0;
298
+ cif_dev->wait_line_bak = 0;
299
+ cif_dev->is_thunderboot = false;
300
+ }
96301 }
97302
98303 static int sditf_get_selection(struct v4l2_subdev *sd,
....@@ -102,18 +307,64 @@
102307 return -EINVAL;
103308 }
104309
310
+static void sditf_reinit_mode(struct sditf_priv *priv, struct rkisp_vicap_mode *mode)
311
+{
312
+ if (mode->rdbk_mode == RKISP_VICAP_RDBK_AIQ) {
313
+ priv->toisp_inf.link_mode = TOISP_NONE;
314
+ } else {
315
+ if (strstr(mode->name, RKISP0_DEVNAME))
316
+ priv->toisp_inf.link_mode = TOISP0;
317
+ else if (strstr(mode->name, RKISP1_DEVNAME))
318
+ priv->toisp_inf.link_mode = TOISP1;
319
+ else if (strstr(mode->name, RKISP_UNITE_DEVNAME))
320
+ priv->toisp_inf.link_mode = TOISP_UNITE;
321
+ else
322
+ priv->toisp_inf.link_mode = TOISP0;
323
+ }
324
+
325
+ v4l2_dbg(1, rkcif_debug, &priv->cif_dev->v4l2_dev,
326
+ "%s, mode->rdbk_mode %d, mode->name %s, link_mode %d\n",
327
+ __func__, mode->rdbk_mode, mode->name, priv->toisp_inf.link_mode);
328
+}
329
+
105330 static long sditf_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
106331 {
107332 struct sditf_priv *priv = to_sditf_priv(sd);
333
+ struct rkisp_vicap_mode *mode;
334
+ struct v4l2_subdev_format fmt;
108335 struct rkcif_device *cif_dev = priv->cif_dev;
109336 struct v4l2_subdev *sensor_sd;
337
+ int *pbuf_num = NULL;
338
+ int ret = 0;
110339
111
- if (!cif_dev->terminal_sensor.sd)
112
- rkcif_update_sensor_info(&cif_dev->stream[0]);
340
+ switch (cmd) {
341
+ case RKISP_VICAP_CMD_MODE:
342
+ mode = (struct rkisp_vicap_mode *)arg;
343
+ memcpy(&priv->mode, mode, sizeof(*mode));
344
+ sditf_reinit_mode(priv, &priv->mode);
345
+ if (priv->is_combine_mode)
346
+ mode->input.merge_num = cif_dev->sditf_cnt;
347
+ else
348
+ mode->input.merge_num = 1;
349
+ mode->input.index = priv->combine_index;
350
+ return 0;
351
+ case RKISP_VICAP_CMD_INIT_BUF:
352
+ pbuf_num = (int *)arg;
353
+ priv->buf_num = *pbuf_num;
354
+ sditf_get_set_fmt(&priv->sd, NULL, &fmt);
355
+ ret = sditf_init_buf(priv);
356
+ return ret;
357
+ case RKMODULE_GET_HDR_CFG:
358
+ if (!cif_dev->terminal_sensor.sd)
359
+ rkcif_update_sensor_info(&cif_dev->stream[0]);
113360
114
- if (cif_dev->terminal_sensor.sd) {
115
- sensor_sd = cif_dev->terminal_sensor.sd;
116
- return v4l2_subdev_call(sensor_sd, core, ioctl, cmd, arg);
361
+ if (cif_dev->terminal_sensor.sd) {
362
+ sensor_sd = cif_dev->terminal_sensor.sd;
363
+ return v4l2_subdev_call(sensor_sd, core, ioctl, cmd, arg);
364
+ }
365
+ break;
366
+ default:
367
+ break;
117368 }
118369
119370 return -EINVAL;
....@@ -123,9 +374,49 @@
123374 static long sditf_compat_ioctl32(struct v4l2_subdev *sd,
124375 unsigned int cmd, unsigned long arg)
125376 {
377
+ void __user *up = compat_ptr(arg);
126378 struct sditf_priv *priv = to_sditf_priv(sd);
127379 struct rkcif_device *cif_dev = priv->cif_dev;
128380 struct v4l2_subdev *sensor_sd;
381
+ struct rkisp_vicap_mode *mode;
382
+ struct rkmodule_hdr_cfg *hdr_cfg;
383
+ int buf_num;
384
+ int ret = 0;
385
+
386
+ switch (cmd) {
387
+ case RKISP_VICAP_CMD_MODE:
388
+ mode = kzalloc(sizeof(*mode), GFP_KERNEL);
389
+ if (!mode) {
390
+ ret = -ENOMEM;
391
+ return ret;
392
+ }
393
+ if (copy_from_user(mode, up, sizeof(*mode))) {
394
+ kfree(mode);
395
+ return -EFAULT;
396
+ }
397
+ ret = sditf_ioctl(sd, cmd, mode);
398
+ kfree(mode);
399
+ return ret;
400
+ case RKISP_VICAP_CMD_INIT_BUF:
401
+ if (copy_from_user(&buf_num, up, sizeof(int)))
402
+ return -EFAULT;
403
+ ret = sditf_ioctl(sd, cmd, &buf_num);
404
+ return ret;
405
+ case RKMODULE_GET_HDR_CFG:
406
+ hdr_cfg = kzalloc(sizeof(*hdr_cfg), GFP_KERNEL);
407
+ if (!hdr_cfg) {
408
+ ret = -ENOMEM;
409
+ return ret;
410
+ }
411
+ if (copy_from_user(hdr_cfg, up, sizeof(*hdr_cfg))) {
412
+ kfree(hdr_cfg);
413
+ return -EFAULT;
414
+ }
415
+ ret = sditf_ioctl(sd, cmd, hdr_cfg);
416
+ return ret;
417
+ default:
418
+ break;
419
+ }
129420
130421 if (!cif_dev->terminal_sensor.sd)
131422 rkcif_update_sensor_info(&cif_dev->stream[0]);
....@@ -139,15 +430,487 @@
139430 }
140431 #endif
141432
433
+static int sditf_channel_enable(struct sditf_priv *priv, int user)
434
+{
435
+ struct rkcif_device *cif_dev = priv->cif_dev;
436
+ struct rkmodule_capture_info *capture_info = &cif_dev->channels[0].capture_info;
437
+ unsigned int ch0 = 0, ch1 = 0, ch2 = 0;
438
+ unsigned int ctrl_val = 0;
439
+ unsigned int int_en = 0;
440
+ unsigned int offset_x = 0;
441
+ unsigned int offset_y = 0;
442
+ unsigned int width = priv->cap_info.width;
443
+ unsigned int height = priv->cap_info.height;
444
+ int csi_idx = cif_dev->csi_host_idx;
445
+
446
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE &&
447
+ priv->toisp_inf.link_mode == TOISP_UNITE) {
448
+ if (capture_info->multi_dev.dev_num != 2 ||
449
+ capture_info->multi_dev.pixel_offset != RKMOUDLE_UNITE_EXTEND_PIXEL) {
450
+ v4l2_err(&cif_dev->v4l2_dev,
451
+ "param error of online mode, combine dev num %d, offset %d\n",
452
+ capture_info->multi_dev.dev_num,
453
+ capture_info->multi_dev.pixel_offset);
454
+ return -EINVAL;
455
+ }
456
+ csi_idx = capture_info->multi_dev.dev_idx[user];
457
+ }
458
+
459
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
460
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
461
+ if (cif_dev->inf_id == RKCIF_MIPI_LVDS)
462
+ ch0 = csi_idx * 4;
463
+ else
464
+ ch0 = 24;//dvp
465
+ ctrl_val = (ch0 << 3) | 0x1;
466
+ if (user == 0)
467
+ int_en = CIF_TOISP0_FS(0);
468
+ else
469
+ int_en = CIF_TOISP1_FS(0);
470
+ priv->toisp_inf.ch_info[0].is_valid = true;
471
+ priv->toisp_inf.ch_info[0].id = ch0;
472
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
473
+ ch0 = cif_dev->csi_host_idx * 4 + 1;
474
+ ch1 = cif_dev->csi_host_idx * 4;
475
+ ctrl_val = (ch0 << 3) | 0x1;
476
+ ctrl_val |= (ch1 << 11) | 0x100;
477
+ if (user == 0)
478
+ int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1);
479
+ else
480
+ int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1);
481
+ priv->toisp_inf.ch_info[0].is_valid = true;
482
+ priv->toisp_inf.ch_info[0].id = ch0;
483
+ priv->toisp_inf.ch_info[1].is_valid = true;
484
+ priv->toisp_inf.ch_info[1].id = ch1;
485
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
486
+ ch0 = cif_dev->csi_host_idx * 4 + 2;
487
+ ch1 = cif_dev->csi_host_idx * 4 + 1;
488
+ ch2 = cif_dev->csi_host_idx * 4;
489
+ ctrl_val = (ch0 << 3) | 0x1;
490
+ ctrl_val |= (ch1 << 11) | 0x100;
491
+ ctrl_val |= (ch2 << 19) | 0x10000;
492
+ if (user == 0)
493
+ int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1) | CIF_TOISP0_FS(2);
494
+ else
495
+ int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1) | CIF_TOISP1_FS(2);
496
+ priv->toisp_inf.ch_info[0].is_valid = true;
497
+ priv->toisp_inf.ch_info[0].id = ch0;
498
+ priv->toisp_inf.ch_info[1].is_valid = true;
499
+ priv->toisp_inf.ch_info[1].id = ch1;
500
+ priv->toisp_inf.ch_info[2].is_valid = true;
501
+ priv->toisp_inf.ch_info[2].id = ch2;
502
+ }
503
+ if (user == 0) {
504
+ if (priv->toisp_inf.link_mode == TOISP_UNITE)
505
+ width = priv->cap_info.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
506
+ rkcif_write_register(cif_dev, CIF_REG_TOISP0_CTRL, ctrl_val);
507
+ if (width && height) {
508
+ rkcif_write_register(cif_dev, CIF_REG_TOISP0_CROP,
509
+ offset_x | (offset_y << 16));
510
+ rkcif_write_register(cif_dev, CIF_REG_TOISP0_SIZE,
511
+ width | (height << 16));
512
+ } else {
513
+ return -EINVAL;
514
+ }
515
+ } else {
516
+ if (priv->toisp_inf.link_mode == TOISP_UNITE) {
517
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE)
518
+ offset_x = 0;
519
+ else
520
+ offset_x = priv->cap_info.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL;
521
+ width = priv->cap_info.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
522
+ }
523
+ rkcif_write_register(cif_dev, CIF_REG_TOISP1_CTRL, ctrl_val);
524
+ if (width && height) {
525
+ rkcif_write_register(cif_dev, CIF_REG_TOISP1_CROP,
526
+ offset_x | (offset_y << 16));
527
+ rkcif_write_register(cif_dev, CIF_REG_TOISP1_SIZE,
528
+ width | (height << 16));
529
+ } else {
530
+ return -EINVAL;
531
+ }
532
+ }
533
+#if IS_ENABLED(CONFIG_CPU_RV1106)
534
+ rv1106_sdmmc_get_lock();
535
+#endif
536
+ rkcif_write_register_or(cif_dev, CIF_REG_GLB_INTEN, int_en);
537
+#if IS_ENABLED(CONFIG_CPU_RV1106)
538
+ rv1106_sdmmc_put_lock();
539
+#endif
540
+ return 0;
541
+}
542
+
543
+static void sditf_channel_disable(struct sditf_priv *priv, int user)
544
+{
545
+ struct rkcif_device *cif_dev = priv->cif_dev;
546
+ unsigned int ctrl_val = 0;
547
+
548
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
549
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
550
+ if (user == 0)
551
+ ctrl_val = CIF_TOISP0_FE(0);
552
+ else
553
+ ctrl_val = CIF_TOISP1_FE(0);
554
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
555
+ if (user == 0)
556
+ ctrl_val = CIF_TOISP0_FE(0) | CIF_TOISP0_FE(1);
557
+ else
558
+ ctrl_val = CIF_TOISP1_FE(0) | CIF_TOISP1_FE(1);
559
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
560
+ if (user == 0)
561
+ ctrl_val = CIF_TOISP0_FE(0) | CIF_TOISP0_FE(1) | CIF_TOISP0_FE(2);
562
+ else
563
+ ctrl_val = CIF_TOISP1_FE(0) | CIF_TOISP1_FE(1) | CIF_TOISP1_FE(2);
564
+ }
565
+#if IS_ENABLED(CONFIG_CPU_RV1106)
566
+ rv1106_sdmmc_get_lock();
567
+#endif
568
+ rkcif_write_register_or(cif_dev, CIF_REG_GLB_INTEN, ctrl_val);
569
+#if IS_ENABLED(CONFIG_CPU_RV1106)
570
+ rv1106_sdmmc_put_lock();
571
+#endif
572
+ priv->toisp_inf.ch_info[0].is_valid = false;
573
+ priv->toisp_inf.ch_info[1].is_valid = false;
574
+ priv->toisp_inf.ch_info[2].is_valid = false;
575
+}
576
+
577
+void sditf_change_to_online(struct sditf_priv *priv)
578
+{
579
+ struct rkcif_device *cif_dev = priv->cif_dev;
580
+
581
+ priv->mode.rdbk_mode = RKISP_VICAP_ONLINE;
582
+ if (priv->toisp_inf.link_mode == TOISP0) {
583
+ sditf_channel_enable(priv, 0);
584
+ } else if (priv->toisp_inf.link_mode == TOISP1) {
585
+ sditf_channel_enable(priv, 1);
586
+ } else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
587
+ sditf_channel_enable(priv, 0);
588
+ sditf_channel_enable(priv, 1);
589
+ }
590
+ if (priv->hdr_cfg.hdr_mode == NO_HDR) {
591
+ rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
592
+ cif_dev->stream[0].is_line_wake_up = false;
593
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
594
+ rkcif_free_rx_buf(&cif_dev->stream[1], priv->buf_num);
595
+ cif_dev->stream[0].is_line_wake_up = false;
596
+ cif_dev->stream[1].is_line_wake_up = false;
597
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
598
+ rkcif_free_rx_buf(&cif_dev->stream[2], priv->buf_num);
599
+ cif_dev->stream[0].is_line_wake_up = false;
600
+ cif_dev->stream[1].is_line_wake_up = false;
601
+ cif_dev->stream[2].is_line_wake_up = false;
602
+ }
603
+ cif_dev->wait_line_cache = 0;
604
+ cif_dev->wait_line = 0;
605
+ cif_dev->wait_line_bak = 0;
606
+}
607
+
608
+static void sditf_check_capture_mode(struct rkcif_device *cif_dev)
609
+{
610
+ struct rkcif_device *dev = NULL;
611
+ int i = 0;
612
+ int toisp_cnt = 0;
613
+
614
+ for (i = 0; i < cif_dev->hw_dev->dev_num; i++) {
615
+ dev = cif_dev->hw_dev->cif_dev[i];
616
+ if (dev && dev->sditf_cnt)
617
+ toisp_cnt++;
618
+ }
619
+ if (cif_dev->is_thunderboot && toisp_cnt == 1)
620
+ cif_dev->is_rdbk_to_online = true;
621
+ else
622
+ cif_dev->is_rdbk_to_online = false;
623
+}
624
+
625
+static int sditf_start_stream(struct sditf_priv *priv)
626
+{
627
+ struct rkcif_device *cif_dev = priv->cif_dev;
628
+ struct v4l2_subdev_format fmt;
629
+ unsigned int mode = RKCIF_STREAM_MODE_TOISP;
630
+ int ret = 0;
631
+
632
+ sditf_check_capture_mode(cif_dev);
633
+ sditf_get_set_fmt(&priv->sd, NULL, &fmt);
634
+ if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
635
+ if (priv->toisp_inf.link_mode == TOISP0) {
636
+ ret = sditf_channel_enable(priv, 0);
637
+ } else if (priv->toisp_inf.link_mode == TOISP1) {
638
+ ret = sditf_channel_enable(priv, 1);
639
+ } else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
640
+ ret = sditf_channel_enable(priv, 0);
641
+ ret |= sditf_channel_enable(priv, 1);
642
+ }
643
+ mode = RKCIF_STREAM_MODE_TOISP;
644
+ } else if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) {
645
+ mode = RKCIF_STREAM_MODE_TOISP_RDBK;
646
+ }
647
+ if (ret)
648
+ return ret;
649
+
650
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
651
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
652
+ ret = rkcif_do_start_stream(&cif_dev->stream[0], mode);
653
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
654
+ ret = rkcif_do_start_stream(&cif_dev->stream[0], mode);
655
+ ret |= rkcif_do_start_stream(&cif_dev->stream[1], mode);
656
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
657
+ ret = rkcif_do_start_stream(&cif_dev->stream[0], mode);
658
+ ret |= rkcif_do_start_stream(&cif_dev->stream[1], mode);
659
+ ret |= rkcif_do_start_stream(&cif_dev->stream[2], mode);
660
+ }
661
+ INIT_LIST_HEAD(&priv->buf_free_list);
662
+ return ret;
663
+}
664
+
665
+static int sditf_stop_stream(struct sditf_priv *priv)
666
+{
667
+ struct rkcif_device *cif_dev = priv->cif_dev;
668
+ unsigned int mode = RKCIF_STREAM_MODE_TOISP;
669
+
670
+ if (priv->toisp_inf.link_mode == TOISP0) {
671
+ sditf_channel_disable(priv, 0);
672
+ } else if (priv->toisp_inf.link_mode == TOISP1) {
673
+ sditf_channel_disable(priv, 1);
674
+ } else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
675
+ sditf_channel_disable(priv, 0);
676
+ sditf_channel_disable(priv, 1);
677
+ }
678
+
679
+ if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE)
680
+ mode = RKCIF_STREAM_MODE_TOISP;
681
+ else if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO)
682
+ mode = RKCIF_STREAM_MODE_TOISP_RDBK;
683
+
684
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
685
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
686
+ rkcif_do_stop_stream(&cif_dev->stream[0], mode);
687
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
688
+ rkcif_do_stop_stream(&cif_dev->stream[0], mode);
689
+ rkcif_do_stop_stream(&cif_dev->stream[1], mode);
690
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
691
+ rkcif_do_stop_stream(&cif_dev->stream[0], mode);
692
+ rkcif_do_stop_stream(&cif_dev->stream[1], mode);
693
+ rkcif_do_stop_stream(&cif_dev->stream[2], mode);
694
+ }
695
+ return 0;
696
+}
697
+
698
+static int sditf_s_stream(struct v4l2_subdev *sd, int on)
699
+{
700
+ struct sditf_priv *priv = to_sditf_priv(sd);
701
+ struct rkcif_device *cif_dev = priv->cif_dev;
702
+ int ret = 0;
703
+
704
+ if (!on && atomic_dec_return(&priv->stream_cnt))
705
+ return 0;
706
+
707
+ if (on && atomic_inc_return(&priv->stream_cnt) > 1)
708
+ return 0;
709
+
710
+ if (cif_dev->chip_id >= CHIP_RK3588_CIF) {
711
+ if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AIQ)
712
+ return 0;
713
+ v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
714
+ "%s, toisp mode %d, hdr %d, stream on %d\n",
715
+ __func__, priv->toisp_inf.link_mode, priv->hdr_cfg.hdr_mode, on);
716
+ if (on) {
717
+ ret = sditf_start_stream(priv);
718
+ } else {
719
+ ret = sditf_stop_stream(priv);
720
+ sditf_free_buf(priv);
721
+ }
722
+
723
+ }
724
+ if (on && ret)
725
+ atomic_dec(&priv->stream_cnt);
726
+ return ret;
727
+}
728
+
729
+static int sditf_s_power(struct v4l2_subdev *sd, int on)
730
+{
731
+ struct sditf_priv *priv = to_sditf_priv(sd);
732
+ struct rkcif_device *cif_dev = priv->cif_dev;
733
+ struct rkcif_vdev_node *node = &cif_dev->stream[0].vnode;
734
+ int ret = 0;
735
+
736
+ if (!on && atomic_dec_return(&priv->power_cnt))
737
+ return 0;
738
+
739
+ if (on && atomic_inc_return(&priv->power_cnt) > 1)
740
+ return 0;
741
+
742
+ if (cif_dev->chip_id >= CHIP_RK3588_CIF) {
743
+ v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
744
+ "%s, toisp mode %d, hdr %d, set power %d\n",
745
+ __func__, priv->toisp_inf.link_mode, priv->hdr_cfg.hdr_mode, on);
746
+ mutex_lock(&cif_dev->stream_lock);
747
+ if (on) {
748
+ ret = pm_runtime_resume_and_get(cif_dev->dev);
749
+ ret |= v4l2_pipeline_pm_get(&node->vdev.entity);
750
+ } else {
751
+ v4l2_pipeline_pm_put(&node->vdev.entity);
752
+ pm_runtime_put_sync(cif_dev->dev);
753
+ priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
754
+ }
755
+ v4l2_info(&node->vdev, "s_power %d, entity use_count %d\n",
756
+ on, node->vdev.entity.use_count);
757
+ mutex_unlock(&cif_dev->stream_lock);
758
+ }
759
+ return ret;
760
+}
761
+
762
+static int sditf_s_rx_buffer(struct v4l2_subdev *sd,
763
+ void *buf, unsigned int *size)
764
+{
765
+ struct sditf_priv *priv = to_sditf_priv(sd);
766
+ struct rkcif_device *cif_dev = priv->cif_dev;
767
+ struct rkcif_sensor_info *sensor = &cif_dev->terminal_sensor;
768
+ struct rkcif_stream *stream = NULL;
769
+ struct rkisp_rx_buf *dbufs;
770
+ struct rkcif_rx_buffer *rx_buf = NULL;
771
+ unsigned long flags, buffree_flags;
772
+ u32 diff_time = 1000000;
773
+ u32 early_time = 0;
774
+ bool is_free = false;
775
+
776
+ if (!buf) {
777
+ v4l2_err(&cif_dev->v4l2_dev, "buf is NULL\n");
778
+ return -EINVAL;
779
+ }
780
+
781
+ dbufs = buf;
782
+ if (cif_dev->hdr.hdr_mode == NO_HDR) {
783
+ if (dbufs->type == BUF_SHORT)
784
+ stream = &cif_dev->stream[0];
785
+ else
786
+ return -EINVAL;
787
+ } else if (cif_dev->hdr.hdr_mode == HDR_X2) {
788
+ if (dbufs->type == BUF_SHORT)
789
+ stream = &cif_dev->stream[1];
790
+ else if (dbufs->type == BUF_MIDDLE)
791
+ stream = &cif_dev->stream[0];
792
+ else
793
+ return -EINVAL;
794
+ } else if (cif_dev->hdr.hdr_mode == HDR_X3) {
795
+ if (dbufs->type == BUF_SHORT)
796
+ stream = &cif_dev->stream[2];
797
+ else if (dbufs->type == BUF_MIDDLE)
798
+ stream = &cif_dev->stream[1];
799
+ else if (dbufs->type == BUF_LONG)
800
+ stream = &cif_dev->stream[0];
801
+ else
802
+ return -EINVAL;
803
+ }
804
+
805
+ if (!stream)
806
+ return -EINVAL;
807
+
808
+ rx_buf = to_cif_rx_buf(dbufs);
809
+ v4l2_dbg(rkcif_debug, 3, &cif_dev->v4l2_dev, "buf back to vicap 0x%x\n",
810
+ (u32)rx_buf->dummy.dma_addr);
811
+ spin_lock_irqsave(&stream->vbq_lock, flags);
812
+ stream->last_rx_buf_idx = dbufs->sequence + 1;
813
+ atomic_inc(&stream->buf_cnt);
814
+
815
+ if (!list_empty(&stream->rx_buf_head) &&
816
+ cif_dev->is_thunderboot &&
817
+ (dbufs->type == BUF_SHORT ||
818
+ (dbufs->type != BUF_SHORT && (!dbufs->is_switch)))) {
819
+ spin_lock_irqsave(&cif_dev->buffree_lock, buffree_flags);
820
+ list_add_tail(&rx_buf->list_free, &priv->buf_free_list);
821
+ spin_unlock_irqrestore(&cif_dev->buffree_lock, buffree_flags);
822
+ atomic_dec(&stream->buf_cnt);
823
+ stream->total_buf_num--;
824
+ schedule_work(&priv->buffree_work.work);
825
+ is_free = true;
826
+ }
827
+
828
+ if (!is_free && (!dbufs->is_switch)) {
829
+ list_add_tail(&rx_buf->list, &stream->rx_buf_head);
830
+ rkcif_assign_check_buffer_update_toisp(stream);
831
+ if (cif_dev->rdbk_debug) {
832
+ u32 offset = 0;
833
+
834
+ offset = rx_buf->dummy.size - stream->pixm.plane_fmt[0].bytesperline * 3;
835
+ memset(rx_buf->dummy.vaddr + offset,
836
+ 0x00, stream->pixm.plane_fmt[0].bytesperline * 3);
837
+ if (cif_dev->is_thunderboot)
838
+ dma_sync_single_for_device(cif_dev->dev,
839
+ rx_buf->dummy.dma_addr + rx_buf->dummy.size -
840
+ stream->pixm.plane_fmt[0].bytesperline * 3,
841
+ stream->pixm.plane_fmt[0].bytesperline * 3,
842
+ DMA_FROM_DEVICE);
843
+ else
844
+ cif_dev->hw_dev->mem_ops->prepare(rx_buf->dummy.mem_priv);
845
+ }
846
+ }
847
+
848
+ if (dbufs->is_switch && dbufs->type == BUF_SHORT) {
849
+ if (stream->is_in_vblank)
850
+ sditf_change_to_online(priv);
851
+ else
852
+ stream->is_change_toisp = true;
853
+ v4l2_dbg(3, rkcif_debug, &cif_dev->v4l2_dev,
854
+ "switch to online mode\n");
855
+ }
856
+ spin_unlock_irqrestore(&stream->vbq_lock, flags);
857
+
858
+ if (dbufs->runtime_us && cif_dev->early_line == 0) {
859
+ if (!cif_dev->sensor_linetime)
860
+ cif_dev->sensor_linetime = rkcif_get_linetime(stream);
861
+ cif_dev->isp_runtime_max = dbufs->runtime_us;
862
+ if (cif_dev->is_thunderboot)
863
+ diff_time = 200000;
864
+ else
865
+ diff_time = 1000000;
866
+ if (dbufs->runtime_us * 1000 + cif_dev->sensor_linetime > diff_time)
867
+ early_time = dbufs->runtime_us * 1000 - diff_time;
868
+ else
869
+ early_time = diff_time;
870
+ cif_dev->early_line = div_u64(early_time, cif_dev->sensor_linetime);
871
+ cif_dev->wait_line_cache = sensor->raw_rect.height - cif_dev->early_line;
872
+ if (cif_dev->rdbk_debug &&
873
+ dbufs->sequence < 15)
874
+ v4l2_info(&cif_dev->v4l2_dev,
875
+ "%s, isp runtime %d, line time %d, early_line %d, line_intr_cnt %d, seq %d, type %d, dma_addr %x\n",
876
+ __func__, dbufs->runtime_us, cif_dev->sensor_linetime,
877
+ cif_dev->early_line, cif_dev->wait_line_cache,
878
+ dbufs->sequence, dbufs->type, (u32)rx_buf->dummy.dma_addr);
879
+ } else {
880
+ if (dbufs->runtime_us < cif_dev->isp_runtime_max) {
881
+ cif_dev->isp_runtime_max = dbufs->runtime_us;
882
+ if (cif_dev->is_thunderboot)
883
+ diff_time = 200000;
884
+ else
885
+ diff_time = 1000000;
886
+ if (dbufs->runtime_us * 1000 + cif_dev->sensor_linetime > diff_time)
887
+ early_time = dbufs->runtime_us * 1000 - diff_time;
888
+ else
889
+ early_time = diff_time;
890
+ cif_dev->early_line = div_u64(early_time, cif_dev->sensor_linetime);
891
+ cif_dev->wait_line_cache = sensor->raw_rect.height - cif_dev->early_line;
892
+ }
893
+ if (cif_dev->rdbk_debug &&
894
+ dbufs->sequence < 15)
895
+ v4l2_info(&cif_dev->v4l2_dev,
896
+ "isp runtime %d, seq %d, type %d, early_line %d, dma addr %x\n",
897
+ dbufs->runtime_us, dbufs->sequence, dbufs->type,
898
+ cif_dev->early_line, (u32)rx_buf->dummy.dma_addr);
899
+ }
900
+ return 0;
901
+}
902
+
142903 static const struct v4l2_subdev_pad_ops sditf_subdev_pad_ops = {
143904 .set_fmt = sditf_get_set_fmt,
144905 .get_fmt = sditf_get_set_fmt,
145906 .get_selection = sditf_get_selection,
907
+ .get_mbus_config = sditf_g_mbus_config,
146908 };
147909
148910 static const struct v4l2_subdev_video_ops sditf_video_ops = {
149911 .g_frame_interval = sditf_g_frame_interval,
150
- .g_mbus_config = sditf_g_mbus_config,
912
+ .s_stream = sditf_s_stream,
913
+ .s_rx_buffer = sditf_s_rx_buffer,
151914 };
152915
153916 static const struct v4l2_subdev_core_ops sditf_core_ops = {
....@@ -155,6 +918,7 @@
155918 #ifdef CONFIG_COMPAT
156919 .compat_ioctl32 = sditf_compat_ioctl32,
157920 #endif
921
+ .s_power = sditf_s_power,
158922 };
159923
160924 static const struct v4l2_subdev_ops sditf_subdev_ops = {
....@@ -188,25 +952,231 @@
188952 return -EINVAL;
189953 }
190954
191
- cif_dev->sditf = sditf;
955
+ cif_dev->sditf[cif_dev->sditf_cnt] = sditf;
192956 sditf->cif_dev = cif_dev;
957
+ cif_dev->sditf_cnt++;
193958
194959 return 0;
960
+}
961
+
962
+struct sensor_async_subdev {
963
+ struct v4l2_async_subdev asd;
964
+ struct v4l2_mbus_config mbus;
965
+ int lanes;
966
+};
967
+
968
+static int sditf_fwnode_parse(struct device *dev,
969
+ struct v4l2_fwnode_endpoint *vep,
970
+ struct v4l2_async_subdev *asd)
971
+{
972
+ struct sensor_async_subdev *s_asd =
973
+ container_of(asd, struct sensor_async_subdev, asd);
974
+ struct v4l2_mbus_config *config = &s_asd->mbus;
975
+
976
+ if (vep->base.port != 0) {
977
+ dev_err(dev, "sditf has only port 0\n");
978
+ return -EINVAL;
979
+ }
980
+
981
+ if (vep->bus_type == V4L2_MBUS_CSI2_DPHY ||
982
+ vep->bus_type == V4L2_MBUS_CSI2_CPHY) {
983
+ config->type = vep->bus_type;
984
+ config->flags = vep->bus.mipi_csi2.flags;
985
+ s_asd->lanes = vep->bus.mipi_csi2.num_data_lanes;
986
+ } else if (vep->bus_type == V4L2_MBUS_CCP2) {
987
+ config->type = vep->bus_type;
988
+ s_asd->lanes = vep->bus.mipi_csi1.data_lane;
989
+ } else {
990
+ dev_err(dev, "type is not supported\n");
991
+ return -EINVAL;
992
+ }
993
+
994
+ switch (s_asd->lanes) {
995
+ case 1:
996
+ config->flags |= V4L2_MBUS_CSI2_1_LANE;
997
+ break;
998
+ case 2:
999
+ config->flags |= V4L2_MBUS_CSI2_2_LANE;
1000
+ break;
1001
+ case 3:
1002
+ config->flags |= V4L2_MBUS_CSI2_3_LANE;
1003
+ break;
1004
+ case 4:
1005
+ config->flags |= V4L2_MBUS_CSI2_4_LANE;
1006
+ break;
1007
+ default:
1008
+ return -EINVAL;
1009
+ }
1010
+
1011
+ return 0;
1012
+}
1013
+
1014
+static int rkcif_sditf_get_ctrl(struct v4l2_ctrl *ctrl)
1015
+{
1016
+ struct sditf_priv *priv = container_of(ctrl->handler,
1017
+ struct sditf_priv,
1018
+ ctrl_handler);
1019
+ struct v4l2_ctrl *sensor_ctrl = NULL;
1020
+
1021
+ switch (ctrl->id) {
1022
+ case V4L2_CID_PIXEL_RATE:
1023
+ if (priv->cif_dev->terminal_sensor.sd) {
1024
+ sensor_ctrl = v4l2_ctrl_find(priv->cif_dev->terminal_sensor.sd->ctrl_handler, V4L2_CID_PIXEL_RATE);
1025
+ if (sensor_ctrl) {
1026
+ ctrl->val = v4l2_ctrl_g_ctrl_int64(sensor_ctrl);
1027
+ __v4l2_ctrl_s_ctrl_int64(priv->pixel_rate, ctrl->val);
1028
+ v4l2_dbg(1, rkcif_debug, &priv->cif_dev->v4l2_dev,
1029
+ "%s, %s pixel rate %d\n",
1030
+ __func__, priv->cif_dev->terminal_sensor.sd->name, ctrl->val);
1031
+ return 0;
1032
+ } else {
1033
+ return -EINVAL;
1034
+ }
1035
+ }
1036
+ return -EINVAL;
1037
+ default:
1038
+ return -EINVAL;
1039
+ }
1040
+}
1041
+
1042
+static const struct v4l2_ctrl_ops rkcif_sditf_ctrl_ops = {
1043
+ .g_volatile_ctrl = rkcif_sditf_get_ctrl,
1044
+};
1045
+
1046
+static int sditf_notifier_bound(struct v4l2_async_notifier *notifier,
1047
+ struct v4l2_subdev *subdev,
1048
+ struct v4l2_async_subdev *asd)
1049
+{
1050
+ struct sditf_priv *sditf = container_of(notifier,
1051
+ struct sditf_priv, notifier);
1052
+ struct media_entity *source_entity, *sink_entity;
1053
+ int ret = 0;
1054
+
1055
+ sditf->sensor_sd = subdev;
1056
+
1057
+ if (sditf->num_sensors == 1) {
1058
+ v4l2_err(subdev,
1059
+ "%s: the num of subdev is beyond %d\n",
1060
+ __func__, sditf->num_sensors);
1061
+ return -EBUSY;
1062
+ }
1063
+
1064
+ if (sditf->sd.entity.pads[0].flags & MEDIA_PAD_FL_SINK) {
1065
+ source_entity = &subdev->entity;
1066
+ sink_entity = &sditf->sd.entity;
1067
+
1068
+ ret = media_create_pad_link(source_entity,
1069
+ 0,
1070
+ sink_entity,
1071
+ 0,
1072
+ MEDIA_LNK_FL_ENABLED);
1073
+ if (ret)
1074
+ v4l2_err(&sditf->sd, "failed to create link for %s\n",
1075
+ sditf->sensor_sd->name);
1076
+ }
1077
+ sditf->sensor_sd = subdev;
1078
+ ++sditf->num_sensors;
1079
+
1080
+ v4l2_err(subdev, "Async registered subdev\n");
1081
+
1082
+ return 0;
1083
+}
1084
+
1085
+static void sditf_notifier_unbind(struct v4l2_async_notifier *notifier,
1086
+ struct v4l2_subdev *sd,
1087
+ struct v4l2_async_subdev *asd)
1088
+{
1089
+ struct sditf_priv *sditf = container_of(notifier,
1090
+ struct sditf_priv,
1091
+ notifier);
1092
+
1093
+ sditf->sensor_sd = NULL;
1094
+}
1095
+
1096
+static const struct v4l2_async_notifier_operations sditf_notifier_ops = {
1097
+ .bound = sditf_notifier_bound,
1098
+ .unbind = sditf_notifier_unbind,
1099
+};
1100
+
1101
+static int sditf_subdev_notifier(struct sditf_priv *sditf)
1102
+{
1103
+ struct v4l2_async_notifier *ntf = &sditf->notifier;
1104
+ int ret;
1105
+
1106
+ v4l2_async_notifier_init(ntf);
1107
+
1108
+ ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
1109
+ sditf->dev, &sditf->notifier,
1110
+ sizeof(struct sensor_async_subdev), 0,
1111
+ sditf_fwnode_parse);
1112
+ if (ret < 0)
1113
+ return ret;
1114
+
1115
+ sditf->sd.subdev_notifier = &sditf->notifier;
1116
+ sditf->notifier.ops = &sditf_notifier_ops;
1117
+
1118
+ ret = v4l2_async_subdev_notifier_register(&sditf->sd, &sditf->notifier);
1119
+ if (ret) {
1120
+ v4l2_err(&sditf->sd,
1121
+ "failed to register async notifier : %d\n",
1122
+ ret);
1123
+ v4l2_async_notifier_cleanup(&sditf->notifier);
1124
+ return ret;
1125
+ }
1126
+
1127
+ return v4l2_async_register_subdev(&sditf->sd);
1951128 }
1961129
1971130 static int rkcif_subdev_media_init(struct sditf_priv *priv)
1981131 {
1991132 struct rkcif_device *cif_dev = priv->cif_dev;
1133
+ struct v4l2_ctrl_handler *handler = &priv->ctrl_handler;
1134
+ unsigned long flags = V4L2_CTRL_FLAG_VOLATILE;
2001135 int ret;
1136
+ int pad_num = 0;
2011137
202
- priv->pads.flags = MEDIA_PAD_FL_SOURCE;
1138
+ if (priv->is_combine_mode) {
1139
+ priv->pads[0].flags = MEDIA_PAD_FL_SINK;
1140
+ priv->pads[1].flags = MEDIA_PAD_FL_SOURCE;
1141
+ pad_num = 2;
1142
+ } else {
1143
+ priv->pads[0].flags = MEDIA_PAD_FL_SOURCE;
1144
+ pad_num = 1;
1145
+ }
2031146 priv->sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_COMPOSER;
204
- ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pads);
1147
+ ret = media_entity_pads_init(&priv->sd.entity, pad_num, priv->pads);
2051148 if (ret < 0)
2061149 return ret;
2071150
208
- strncpy(priv->sd.name, dev_name(cif_dev->dev), sizeof(priv->sd.name));
1151
+ ret = v4l2_ctrl_handler_init(handler, 1);
1152
+ if (ret)
1153
+ return ret;
1154
+ priv->pixel_rate = v4l2_ctrl_new_std(handler, &rkcif_sditf_ctrl_ops,
1155
+ V4L2_CID_PIXEL_RATE,
1156
+ 0, SDITF_PIXEL_RATE_MAX,
1157
+ 1, SDITF_PIXEL_RATE_MAX);
1158
+ if (priv->pixel_rate)
1159
+ priv->pixel_rate->flags |= flags;
1160
+ priv->sd.ctrl_handler = handler;
1161
+ if (handler->error) {
1162
+ v4l2_ctrl_handler_free(handler);
1163
+ return handler->error;
1164
+ }
2091165
1166
+ strncpy(priv->sd.name, dev_name(cif_dev->dev), sizeof(priv->sd.name));
1167
+ priv->cap_info.width = 0;
1168
+ priv->cap_info.height = 0;
1169
+ priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
1170
+ priv->toisp_inf.link_mode = TOISP_NONE;
1171
+ priv->toisp_inf.ch_info[0].is_valid = false;
1172
+ priv->toisp_inf.ch_info[1].is_valid = false;
1173
+ priv->toisp_inf.ch_info[2].is_valid = false;
1174
+ if (priv->is_combine_mode)
1175
+ sditf_subdev_notifier(priv);
1176
+ atomic_set(&priv->power_cnt, 0);
1177
+ atomic_set(&priv->stream_cnt, 0);
1178
+ INIT_WORK(&priv->buffree_work.work, sditf_buffree_work);
1179
+ INIT_LIST_HEAD(&priv->buf_free_list);
2101180 return 0;
2111181 }
2121182
....@@ -215,6 +1185,7 @@
2151185 struct device *dev = &pdev->dev;
2161186 struct v4l2_subdev *sd;
2171187 struct sditf_priv *priv;
1188
+ struct device_node *node = dev->of_node;
2181189 int ret;
2191190
2201191 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
....@@ -230,7 +1201,19 @@
2301201
2311202 platform_set_drvdata(pdev, &sd->entity);
2321203
233
- rkcif_sditf_attach_cifdev(priv);
1204
+ ret = rkcif_sditf_attach_cifdev(priv);
1205
+ if (ret < 0)
1206
+ return ret;
1207
+
1208
+ ret = of_property_read_u32(node,
1209
+ "rockchip,combine-index",
1210
+ &priv->combine_index);
1211
+ if (ret) {
1212
+ priv->is_combine_mode = false;
1213
+ priv->combine_index = 0;
1214
+ } else {
1215
+ priv->is_combine_mode = true;
1216
+ }
2341217 ret = rkcif_subdev_media_init(priv);
2351218 if (ret < 0)
2361219 return ret;
....@@ -250,21 +1233,6 @@
2501233 return 0;
2511234 }
2521235
253
-static int sditf_runtime_suspend(struct device *dev)
254
-{
255
- return 0;
256
-}
257
-
258
-static int sditf_runtime_resume(struct device *dev)
259
-{
260
- return 0;
261
-}
262
-
263
-static const struct dev_pm_ops rkcif_subdev_pm_ops = {
264
- SET_RUNTIME_PM_OPS(sditf_runtime_suspend,
265
- sditf_runtime_resume, NULL)
266
-};
267
-
2681236 static const struct of_device_id rkcif_subdev_match_id[] = {
2691237 {
2701238 .compatible = "rockchip,rkcif-sditf",
....@@ -278,7 +1246,6 @@
2781246 .remove = rkcif_subdev_remove,
2791247 .driver = {
2801248 .name = "rkcif_sditf",
281
- .pm = &rkcif_subdev_pm_ops,
2821249 .of_match_table = rkcif_subdev_match_id,
2831250 },
2841251 };