forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-06 08f87f769b595151be1afeff53e144f543faa614
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,61 @@
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
+ mode->input.merge_num = cif_dev->sditf_cnt;
346
+ mode->input.index = priv->combine_index;
347
+ return 0;
348
+ case RKISP_VICAP_CMD_INIT_BUF:
349
+ pbuf_num = (int *)arg;
350
+ priv->buf_num = *pbuf_num;
351
+ sditf_get_set_fmt(&priv->sd, NULL, &fmt);
352
+ ret = sditf_init_buf(priv);
353
+ return ret;
354
+ case RKMODULE_GET_HDR_CFG:
355
+ if (!cif_dev->terminal_sensor.sd)
356
+ rkcif_update_sensor_info(&cif_dev->stream[0]);
113357
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);
358
+ if (cif_dev->terminal_sensor.sd) {
359
+ sensor_sd = cif_dev->terminal_sensor.sd;
360
+ return v4l2_subdev_call(sensor_sd, core, ioctl, cmd, arg);
361
+ }
362
+ break;
363
+ default:
364
+ break;
117365 }
118366
119367 return -EINVAL;
....@@ -123,9 +371,49 @@
123371 static long sditf_compat_ioctl32(struct v4l2_subdev *sd,
124372 unsigned int cmd, unsigned long arg)
125373 {
374
+ void __user *up = compat_ptr(arg);
126375 struct sditf_priv *priv = to_sditf_priv(sd);
127376 struct rkcif_device *cif_dev = priv->cif_dev;
128377 struct v4l2_subdev *sensor_sd;
378
+ struct rkisp_vicap_mode *mode;
379
+ struct rkmodule_hdr_cfg *hdr_cfg;
380
+ int buf_num;
381
+ int ret = 0;
382
+
383
+ switch (cmd) {
384
+ case RKISP_VICAP_CMD_MODE:
385
+ mode = kzalloc(sizeof(*mode), GFP_KERNEL);
386
+ if (!mode) {
387
+ ret = -ENOMEM;
388
+ return ret;
389
+ }
390
+ if (copy_from_user(mode, up, sizeof(*mode))) {
391
+ kfree(mode);
392
+ return -EFAULT;
393
+ }
394
+ ret = sditf_ioctl(sd, cmd, mode);
395
+ kfree(mode);
396
+ return ret;
397
+ case RKISP_VICAP_CMD_INIT_BUF:
398
+ if (copy_from_user(&buf_num, up, sizeof(int)))
399
+ return -EFAULT;
400
+ ret = sditf_ioctl(sd, cmd, &buf_num);
401
+ return ret;
402
+ case RKMODULE_GET_HDR_CFG:
403
+ hdr_cfg = kzalloc(sizeof(*hdr_cfg), GFP_KERNEL);
404
+ if (!hdr_cfg) {
405
+ ret = -ENOMEM;
406
+ return ret;
407
+ }
408
+ if (copy_from_user(hdr_cfg, up, sizeof(*hdr_cfg))) {
409
+ kfree(hdr_cfg);
410
+ return -EFAULT;
411
+ }
412
+ ret = sditf_ioctl(sd, cmd, hdr_cfg);
413
+ return ret;
414
+ default:
415
+ break;
416
+ }
129417
130418 if (!cif_dev->terminal_sensor.sd)
131419 rkcif_update_sensor_info(&cif_dev->stream[0]);
....@@ -139,15 +427,460 @@
139427 }
140428 #endif
141429
430
+static int sditf_channel_enable(struct sditf_priv *priv, int user)
431
+{
432
+ struct rkcif_device *cif_dev = priv->cif_dev;
433
+ unsigned int ch0 = 0, ch1 = 0, ch2 = 0;
434
+ unsigned int ctrl_val = 0;
435
+ unsigned int int_en = 0;
436
+ unsigned int offset_x = 0;
437
+ unsigned int offset_y = 0;
438
+ unsigned int width = priv->cap_info.width;
439
+ unsigned int height = priv->cap_info.height;
440
+
441
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
442
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
443
+ if (cif_dev->inf_id == RKCIF_MIPI_LVDS)
444
+ ch0 = cif_dev->csi_host_idx * 4;
445
+ else
446
+ ch0 = 24;//dvp
447
+ ctrl_val = (ch0 << 3) | 0x1;
448
+ if (user == 0)
449
+ int_en = CIF_TOISP0_FS(0);
450
+ else
451
+ int_en = CIF_TOISP1_FS(0);
452
+ priv->toisp_inf.ch_info[0].is_valid = true;
453
+ priv->toisp_inf.ch_info[0].id = ch0;
454
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
455
+ ch0 = cif_dev->csi_host_idx * 4 + 1;
456
+ ch1 = cif_dev->csi_host_idx * 4;
457
+ ctrl_val = (ch0 << 3) | 0x1;
458
+ ctrl_val |= (ch1 << 11) | 0x100;
459
+ if (user == 0)
460
+ int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1);
461
+ else
462
+ int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1);
463
+ priv->toisp_inf.ch_info[0].is_valid = true;
464
+ priv->toisp_inf.ch_info[0].id = ch0;
465
+ priv->toisp_inf.ch_info[1].is_valid = true;
466
+ priv->toisp_inf.ch_info[1].id = ch1;
467
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
468
+ ch0 = cif_dev->csi_host_idx * 4 + 2;
469
+ ch1 = cif_dev->csi_host_idx * 4 + 1;
470
+ ch2 = cif_dev->csi_host_idx * 4;
471
+ ctrl_val = (ch0 << 3) | 0x1;
472
+ ctrl_val |= (ch1 << 11) | 0x100;
473
+ ctrl_val |= (ch2 << 19) | 0x10000;
474
+ if (user == 0)
475
+ int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1) | CIF_TOISP0_FS(2);
476
+ else
477
+ int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1) | CIF_TOISP1_FS(2);
478
+ priv->toisp_inf.ch_info[0].is_valid = true;
479
+ priv->toisp_inf.ch_info[0].id = ch0;
480
+ priv->toisp_inf.ch_info[1].is_valid = true;
481
+ priv->toisp_inf.ch_info[1].id = ch1;
482
+ priv->toisp_inf.ch_info[2].is_valid = true;
483
+ priv->toisp_inf.ch_info[2].id = ch2;
484
+ }
485
+ if (user == 0) {
486
+ if (priv->toisp_inf.link_mode == TOISP_UNITE)
487
+ width = priv->cap_info.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
488
+ rkcif_write_register(cif_dev, CIF_REG_TOISP0_CTRL, ctrl_val);
489
+ if (width && height) {
490
+ rkcif_write_register(cif_dev, CIF_REG_TOISP0_CROP,
491
+ offset_x | (offset_y << 16));
492
+ rkcif_write_register(cif_dev, CIF_REG_TOISP0_SIZE,
493
+ width | (height << 16));
494
+ } else {
495
+ return -EINVAL;
496
+ }
497
+ } else {
498
+ if (priv->toisp_inf.link_mode == TOISP_UNITE) {
499
+ offset_x = priv->cap_info.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL;
500
+ width = priv->cap_info.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
501
+ }
502
+ rkcif_write_register(cif_dev, CIF_REG_TOISP1_CTRL, ctrl_val);
503
+ if (width && height) {
504
+ rkcif_write_register(cif_dev, CIF_REG_TOISP1_CROP,
505
+ offset_x | (offset_y << 16));
506
+ rkcif_write_register(cif_dev, CIF_REG_TOISP1_SIZE,
507
+ width | (height << 16));
508
+ } else {
509
+ return -EINVAL;
510
+ }
511
+ }
512
+#if IS_ENABLED(CONFIG_CPU_RV1106)
513
+ rv1106_sdmmc_get_lock();
514
+#endif
515
+ rkcif_write_register_or(cif_dev, CIF_REG_GLB_INTEN, int_en);
516
+#if IS_ENABLED(CONFIG_CPU_RV1106)
517
+ rv1106_sdmmc_put_lock();
518
+#endif
519
+ return 0;
520
+}
521
+
522
+static void sditf_channel_disable(struct sditf_priv *priv, int user)
523
+{
524
+ struct rkcif_device *cif_dev = priv->cif_dev;
525
+ unsigned int ctrl_val = 0;
526
+
527
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
528
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
529
+ if (user == 0)
530
+ ctrl_val = CIF_TOISP0_FE(0);
531
+ else
532
+ ctrl_val = CIF_TOISP1_FE(0);
533
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
534
+ if (user == 0)
535
+ ctrl_val = CIF_TOISP0_FE(0) | CIF_TOISP0_FE(1);
536
+ else
537
+ ctrl_val = CIF_TOISP1_FE(0) | CIF_TOISP1_FE(1);
538
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
539
+ if (user == 0)
540
+ ctrl_val = CIF_TOISP0_FE(0) | CIF_TOISP0_FE(1) | CIF_TOISP0_FE(2);
541
+ else
542
+ ctrl_val = CIF_TOISP1_FE(0) | CIF_TOISP1_FE(1) | CIF_TOISP1_FE(2);
543
+ }
544
+#if IS_ENABLED(CONFIG_CPU_RV1106)
545
+ rv1106_sdmmc_get_lock();
546
+#endif
547
+ rkcif_write_register_or(cif_dev, CIF_REG_GLB_INTEN, ctrl_val);
548
+#if IS_ENABLED(CONFIG_CPU_RV1106)
549
+ rv1106_sdmmc_put_lock();
550
+#endif
551
+ priv->toisp_inf.ch_info[0].is_valid = false;
552
+ priv->toisp_inf.ch_info[1].is_valid = false;
553
+ priv->toisp_inf.ch_info[2].is_valid = false;
554
+}
555
+
556
+void sditf_change_to_online(struct sditf_priv *priv)
557
+{
558
+ struct rkcif_device *cif_dev = priv->cif_dev;
559
+
560
+ priv->mode.rdbk_mode = RKISP_VICAP_ONLINE;
561
+ if (priv->toisp_inf.link_mode == TOISP0) {
562
+ sditf_channel_enable(priv, 0);
563
+ } else if (priv->toisp_inf.link_mode == TOISP1) {
564
+ sditf_channel_enable(priv, 1);
565
+ } else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
566
+ sditf_channel_enable(priv, 0);
567
+ sditf_channel_enable(priv, 1);
568
+ }
569
+ if (priv->hdr_cfg.hdr_mode == NO_HDR) {
570
+ rkcif_free_rx_buf(&cif_dev->stream[0], priv->buf_num);
571
+ cif_dev->stream[0].is_line_wake_up = false;
572
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
573
+ rkcif_free_rx_buf(&cif_dev->stream[1], priv->buf_num);
574
+ cif_dev->stream[0].is_line_wake_up = false;
575
+ cif_dev->stream[1].is_line_wake_up = false;
576
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
577
+ rkcif_free_rx_buf(&cif_dev->stream[2], priv->buf_num);
578
+ cif_dev->stream[0].is_line_wake_up = false;
579
+ cif_dev->stream[1].is_line_wake_up = false;
580
+ cif_dev->stream[2].is_line_wake_up = false;
581
+ }
582
+ cif_dev->wait_line_cache = 0;
583
+ cif_dev->wait_line = 0;
584
+ cif_dev->wait_line_bak = 0;
585
+}
586
+
587
+static void sditf_check_capture_mode(struct rkcif_device *cif_dev)
588
+{
589
+ struct rkcif_device *dev = NULL;
590
+ int i = 0;
591
+ int toisp_cnt = 0;
592
+
593
+ for (i = 0; i < cif_dev->hw_dev->dev_num; i++) {
594
+ dev = cif_dev->hw_dev->cif_dev[i];
595
+ if (dev && dev->sditf_cnt)
596
+ toisp_cnt++;
597
+ }
598
+ if (cif_dev->is_thunderboot && toisp_cnt == 1)
599
+ cif_dev->is_rdbk_to_online = true;
600
+ else
601
+ cif_dev->is_rdbk_to_online = false;
602
+}
603
+
604
+static int sditf_start_stream(struct sditf_priv *priv)
605
+{
606
+ struct rkcif_device *cif_dev = priv->cif_dev;
607
+ struct v4l2_subdev_format fmt;
608
+ unsigned int mode = RKCIF_STREAM_MODE_TOISP;
609
+
610
+ sditf_check_capture_mode(cif_dev);
611
+ sditf_get_set_fmt(&priv->sd, NULL, &fmt);
612
+ if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
613
+ if (priv->toisp_inf.link_mode == TOISP0) {
614
+ sditf_channel_enable(priv, 0);
615
+ } else if (priv->toisp_inf.link_mode == TOISP1) {
616
+ sditf_channel_enable(priv, 1);
617
+ } else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
618
+ sditf_channel_enable(priv, 0);
619
+ sditf_channel_enable(priv, 1);
620
+ }
621
+ mode = RKCIF_STREAM_MODE_TOISP;
622
+ } else if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) {
623
+ mode = RKCIF_STREAM_MODE_TOISP_RDBK;
624
+ }
625
+
626
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
627
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
628
+ rkcif_do_start_stream(&cif_dev->stream[0], mode);
629
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
630
+ rkcif_do_start_stream(&cif_dev->stream[0], mode);
631
+ rkcif_do_start_stream(&cif_dev->stream[1], mode);
632
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
633
+ rkcif_do_start_stream(&cif_dev->stream[0], mode);
634
+ rkcif_do_start_stream(&cif_dev->stream[1], mode);
635
+ rkcif_do_start_stream(&cif_dev->stream[2], mode);
636
+ }
637
+ INIT_LIST_HEAD(&priv->buf_free_list);
638
+ return 0;
639
+}
640
+
641
+static int sditf_stop_stream(struct sditf_priv *priv)
642
+{
643
+ struct rkcif_device *cif_dev = priv->cif_dev;
644
+ unsigned int mode = RKCIF_STREAM_MODE_TOISP;
645
+
646
+ if (priv->toisp_inf.link_mode == TOISP0) {
647
+ sditf_channel_disable(priv, 0);
648
+ } else if (priv->toisp_inf.link_mode == TOISP1) {
649
+ sditf_channel_disable(priv, 1);
650
+ } else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
651
+ sditf_channel_disable(priv, 0);
652
+ sditf_channel_disable(priv, 1);
653
+ }
654
+
655
+ if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE)
656
+ mode = RKCIF_STREAM_MODE_TOISP;
657
+ else if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO)
658
+ mode = RKCIF_STREAM_MODE_TOISP_RDBK;
659
+
660
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
661
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
662
+ rkcif_do_stop_stream(&cif_dev->stream[0], mode);
663
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
664
+ rkcif_do_stop_stream(&cif_dev->stream[0], mode);
665
+ rkcif_do_stop_stream(&cif_dev->stream[1], mode);
666
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
667
+ rkcif_do_stop_stream(&cif_dev->stream[0], mode);
668
+ rkcif_do_stop_stream(&cif_dev->stream[1], mode);
669
+ rkcif_do_stop_stream(&cif_dev->stream[2], mode);
670
+ }
671
+ return 0;
672
+}
673
+
674
+static int sditf_s_stream(struct v4l2_subdev *sd, int on)
675
+{
676
+ struct sditf_priv *priv = to_sditf_priv(sd);
677
+ struct rkcif_device *cif_dev = priv->cif_dev;
678
+ int ret = 0;
679
+
680
+ if (!on && atomic_dec_return(&priv->stream_cnt))
681
+ return 0;
682
+
683
+ if (on && atomic_inc_return(&priv->stream_cnt) > 1)
684
+ return 0;
685
+
686
+ if (cif_dev->chip_id >= CHIP_RK3588_CIF) {
687
+ if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AIQ)
688
+ return 0;
689
+ v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
690
+ "%s, toisp mode %d, hdr %d, stream on %d\n",
691
+ __func__, priv->toisp_inf.link_mode, priv->hdr_cfg.hdr_mode, on);
692
+ if (on) {
693
+ ret = sditf_start_stream(priv);
694
+ } else {
695
+ ret = sditf_stop_stream(priv);
696
+ sditf_free_buf(priv);
697
+ }
698
+
699
+ }
700
+ return ret;
701
+}
702
+
703
+static int sditf_s_power(struct v4l2_subdev *sd, int on)
704
+{
705
+ struct sditf_priv *priv = to_sditf_priv(sd);
706
+ struct rkcif_device *cif_dev = priv->cif_dev;
707
+ struct rkcif_vdev_node *node = &cif_dev->stream[0].vnode;
708
+ int ret = 0;
709
+
710
+ if (!on && atomic_dec_return(&priv->power_cnt))
711
+ return 0;
712
+
713
+ if (on && atomic_inc_return(&priv->power_cnt) > 1)
714
+ return 0;
715
+
716
+ if (cif_dev->chip_id >= CHIP_RK3588_CIF) {
717
+ v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
718
+ "%s, toisp mode %d, hdr %d, set power %d\n",
719
+ __func__, priv->toisp_inf.link_mode, priv->hdr_cfg.hdr_mode, on);
720
+ mutex_lock(&cif_dev->stream_lock);
721
+ if (on) {
722
+ ret = pm_runtime_resume_and_get(cif_dev->dev);
723
+ ret |= v4l2_pipeline_pm_get(&node->vdev.entity);
724
+ } else {
725
+ v4l2_pipeline_pm_put(&node->vdev.entity);
726
+ pm_runtime_put_sync(cif_dev->dev);
727
+ }
728
+ v4l2_info(&node->vdev, "s_power %d, entity use_count %d\n",
729
+ on, node->vdev.entity.use_count);
730
+ mutex_unlock(&cif_dev->stream_lock);
731
+ }
732
+ return ret;
733
+}
734
+
735
+static int sditf_s_rx_buffer(struct v4l2_subdev *sd,
736
+ void *buf, unsigned int *size)
737
+{
738
+ struct sditf_priv *priv = to_sditf_priv(sd);
739
+ struct rkcif_device *cif_dev = priv->cif_dev;
740
+ struct rkcif_sensor_info *sensor = &cif_dev->terminal_sensor;
741
+ struct rkcif_stream *stream = NULL;
742
+ struct rkisp_rx_buf *dbufs;
743
+ struct rkcif_rx_buffer *rx_buf = NULL;
744
+ unsigned long flags, buffree_flags;
745
+ u32 diff_time = 1000000;
746
+ u32 early_time = 0;
747
+ bool is_free = false;
748
+
749
+ if (!buf) {
750
+ v4l2_err(&cif_dev->v4l2_dev, "buf is NULL\n");
751
+ return -EINVAL;
752
+ }
753
+
754
+ dbufs = buf;
755
+ if (cif_dev->hdr.hdr_mode == NO_HDR) {
756
+ if (dbufs->type == BUF_SHORT)
757
+ stream = &cif_dev->stream[0];
758
+ else
759
+ return -EINVAL;
760
+ } else if (cif_dev->hdr.hdr_mode == HDR_X2) {
761
+ if (dbufs->type == BUF_SHORT)
762
+ stream = &cif_dev->stream[1];
763
+ else if (dbufs->type == BUF_MIDDLE)
764
+ stream = &cif_dev->stream[0];
765
+ else
766
+ return -EINVAL;
767
+ } else if (cif_dev->hdr.hdr_mode == HDR_X3) {
768
+ if (dbufs->type == BUF_SHORT)
769
+ stream = &cif_dev->stream[2];
770
+ else if (dbufs->type == BUF_MIDDLE)
771
+ stream = &cif_dev->stream[1];
772
+ else if (dbufs->type == BUF_LONG)
773
+ stream = &cif_dev->stream[0];
774
+ else
775
+ return -EINVAL;
776
+ }
777
+
778
+ if (!stream)
779
+ return -EINVAL;
780
+
781
+ rx_buf = to_cif_rx_buf(dbufs);
782
+
783
+ spin_lock_irqsave(&stream->vbq_lock, flags);
784
+ stream->buf_num_toisp++;
785
+ stream->last_rx_buf_idx = dbufs->sequence + 1;
786
+
787
+ if (!list_empty(&stream->rx_buf_head) &&
788
+ cif_dev->is_thunderboot &&
789
+ (dbufs->type == BUF_SHORT ||
790
+ (dbufs->type != BUF_SHORT && (!dbufs->is_switch)))) {
791
+ spin_lock_irqsave(&cif_dev->buffree_lock, buffree_flags);
792
+ list_add_tail(&rx_buf->list_free, &priv->buf_free_list);
793
+ spin_unlock_irqrestore(&cif_dev->buffree_lock, buffree_flags);
794
+ schedule_work(&priv->buffree_work.work);
795
+ is_free = true;
796
+ }
797
+
798
+ if (!is_free && (!dbufs->is_switch)) {
799
+ list_add_tail(&rx_buf->list, &stream->rx_buf_head);
800
+ rkcif_assign_check_buffer_update_toisp(stream);
801
+ if (cif_dev->rdbk_debug) {
802
+ u32 offset = 0;
803
+
804
+ offset = rx_buf->dummy.size - stream->pixm.plane_fmt[0].bytesperline * 3;
805
+ memset(rx_buf->dummy.vaddr + offset,
806
+ 0x00, stream->pixm.plane_fmt[0].bytesperline * 3);
807
+ if (cif_dev->is_thunderboot)
808
+ dma_sync_single_for_device(cif_dev->dev,
809
+ rx_buf->dummy.dma_addr + rx_buf->dummy.size -
810
+ stream->pixm.plane_fmt[0].bytesperline * 3,
811
+ stream->pixm.plane_fmt[0].bytesperline * 3,
812
+ DMA_FROM_DEVICE);
813
+ else
814
+ cif_dev->hw_dev->mem_ops->prepare(rx_buf->dummy.mem_priv);
815
+ }
816
+ }
817
+
818
+ if (dbufs->is_switch && dbufs->type == BUF_SHORT) {
819
+ if (stream->is_in_vblank)
820
+ sditf_change_to_online(priv);
821
+ else
822
+ stream->is_change_toisp = true;
823
+ v4l2_dbg(3, rkcif_debug, &cif_dev->v4l2_dev,
824
+ "switch to online mode\n");
825
+ }
826
+ spin_unlock_irqrestore(&stream->vbq_lock, flags);
827
+
828
+ if (dbufs->runtime_us && cif_dev->early_line == 0) {
829
+ if (!cif_dev->sensor_linetime)
830
+ cif_dev->sensor_linetime = rkcif_get_linetime(stream);
831
+ cif_dev->isp_runtime_max = dbufs->runtime_us;
832
+ if (cif_dev->is_thunderboot)
833
+ diff_time = 200000;
834
+ else
835
+ diff_time = 1000000;
836
+ if (dbufs->runtime_us * 1000 + cif_dev->sensor_linetime > diff_time)
837
+ early_time = dbufs->runtime_us * 1000 - diff_time;
838
+ else
839
+ early_time = diff_time;
840
+ cif_dev->early_line = div_u64(early_time, cif_dev->sensor_linetime);
841
+ cif_dev->wait_line_cache = sensor->raw_rect.height - cif_dev->early_line;
842
+ if (cif_dev->rdbk_debug &&
843
+ dbufs->sequence < 15)
844
+ v4l2_info(&cif_dev->v4l2_dev,
845
+ "%s, isp runtime %d, line time %d, early_line %d, line_intr_cnt %d, seq %d, type %d, dma_addr %x\n",
846
+ __func__, dbufs->runtime_us, cif_dev->sensor_linetime,
847
+ cif_dev->early_line, cif_dev->wait_line_cache,
848
+ dbufs->sequence, dbufs->type, (u32)rx_buf->dummy.dma_addr);
849
+ } else {
850
+ if (dbufs->runtime_us < cif_dev->isp_runtime_max) {
851
+ cif_dev->isp_runtime_max = dbufs->runtime_us;
852
+ if (cif_dev->is_thunderboot)
853
+ diff_time = 200000;
854
+ else
855
+ diff_time = 1000000;
856
+ if (dbufs->runtime_us * 1000 + cif_dev->sensor_linetime > diff_time)
857
+ early_time = dbufs->runtime_us * 1000 - diff_time;
858
+ else
859
+ early_time = diff_time;
860
+ cif_dev->early_line = div_u64(early_time, cif_dev->sensor_linetime);
861
+ cif_dev->wait_line_cache = sensor->raw_rect.height - cif_dev->early_line;
862
+ }
863
+ if (cif_dev->rdbk_debug &&
864
+ dbufs->sequence < 15)
865
+ v4l2_info(&cif_dev->v4l2_dev,
866
+ "isp runtime %d, seq %d, type %d, early_line %d, dma addr %x\n",
867
+ dbufs->runtime_us, dbufs->sequence, dbufs->type,
868
+ cif_dev->early_line, (u32)rx_buf->dummy.dma_addr);
869
+ }
870
+ return 0;
871
+}
872
+
142873 static const struct v4l2_subdev_pad_ops sditf_subdev_pad_ops = {
143874 .set_fmt = sditf_get_set_fmt,
144875 .get_fmt = sditf_get_set_fmt,
145876 .get_selection = sditf_get_selection,
877
+ .get_mbus_config = sditf_g_mbus_config,
146878 };
147879
148880 static const struct v4l2_subdev_video_ops sditf_video_ops = {
149881 .g_frame_interval = sditf_g_frame_interval,
150
- .g_mbus_config = sditf_g_mbus_config,
882
+ .s_stream = sditf_s_stream,
883
+ .s_rx_buffer = sditf_s_rx_buffer,
151884 };
152885
153886 static const struct v4l2_subdev_core_ops sditf_core_ops = {
....@@ -155,6 +888,7 @@
155888 #ifdef CONFIG_COMPAT
156889 .compat_ioctl32 = sditf_compat_ioctl32,
157890 #endif
891
+ .s_power = sditf_s_power,
158892 };
159893
160894 static const struct v4l2_subdev_ops sditf_subdev_ops = {
....@@ -188,25 +922,231 @@
188922 return -EINVAL;
189923 }
190924
191
- cif_dev->sditf = sditf;
925
+ cif_dev->sditf[cif_dev->sditf_cnt] = sditf;
192926 sditf->cif_dev = cif_dev;
927
+ cif_dev->sditf_cnt++;
193928
194929 return 0;
930
+}
931
+
932
+struct sensor_async_subdev {
933
+ struct v4l2_async_subdev asd;
934
+ struct v4l2_mbus_config mbus;
935
+ int lanes;
936
+};
937
+
938
+static int sditf_fwnode_parse(struct device *dev,
939
+ struct v4l2_fwnode_endpoint *vep,
940
+ struct v4l2_async_subdev *asd)
941
+{
942
+ struct sensor_async_subdev *s_asd =
943
+ container_of(asd, struct sensor_async_subdev, asd);
944
+ struct v4l2_mbus_config *config = &s_asd->mbus;
945
+
946
+ if (vep->base.port != 0) {
947
+ dev_err(dev, "sditf has only port 0\n");
948
+ return -EINVAL;
949
+ }
950
+
951
+ if (vep->bus_type == V4L2_MBUS_CSI2_DPHY ||
952
+ vep->bus_type == V4L2_MBUS_CSI2_CPHY) {
953
+ config->type = vep->bus_type;
954
+ config->flags = vep->bus.mipi_csi2.flags;
955
+ s_asd->lanes = vep->bus.mipi_csi2.num_data_lanes;
956
+ } else if (vep->bus_type == V4L2_MBUS_CCP2) {
957
+ config->type = vep->bus_type;
958
+ s_asd->lanes = vep->bus.mipi_csi1.data_lane;
959
+ } else {
960
+ dev_err(dev, "type is not supported\n");
961
+ return -EINVAL;
962
+ }
963
+
964
+ switch (s_asd->lanes) {
965
+ case 1:
966
+ config->flags |= V4L2_MBUS_CSI2_1_LANE;
967
+ break;
968
+ case 2:
969
+ config->flags |= V4L2_MBUS_CSI2_2_LANE;
970
+ break;
971
+ case 3:
972
+ config->flags |= V4L2_MBUS_CSI2_3_LANE;
973
+ break;
974
+ case 4:
975
+ config->flags |= V4L2_MBUS_CSI2_4_LANE;
976
+ break;
977
+ default:
978
+ return -EINVAL;
979
+ }
980
+
981
+ return 0;
982
+}
983
+
984
+static int rkcif_sditf_get_ctrl(struct v4l2_ctrl *ctrl)
985
+{
986
+ struct sditf_priv *priv = container_of(ctrl->handler,
987
+ struct sditf_priv,
988
+ ctrl_handler);
989
+ struct v4l2_ctrl *sensor_ctrl = NULL;
990
+
991
+ switch (ctrl->id) {
992
+ case V4L2_CID_PIXEL_RATE:
993
+ if (priv->cif_dev->terminal_sensor.sd) {
994
+ sensor_ctrl = v4l2_ctrl_find(priv->cif_dev->terminal_sensor.sd->ctrl_handler, V4L2_CID_PIXEL_RATE);
995
+ if (sensor_ctrl) {
996
+ ctrl->val = v4l2_ctrl_g_ctrl_int64(sensor_ctrl);
997
+ __v4l2_ctrl_s_ctrl_int64(priv->pixel_rate, ctrl->val);
998
+ v4l2_dbg(1, rkcif_debug, &priv->cif_dev->v4l2_dev,
999
+ "%s, %s pixel rate %d\n",
1000
+ __func__, priv->cif_dev->terminal_sensor.sd->name, ctrl->val);
1001
+ return 0;
1002
+ } else {
1003
+ return -EINVAL;
1004
+ }
1005
+ }
1006
+ return -EINVAL;
1007
+ default:
1008
+ return -EINVAL;
1009
+ }
1010
+}
1011
+
1012
+static const struct v4l2_ctrl_ops rkcif_sditf_ctrl_ops = {
1013
+ .g_volatile_ctrl = rkcif_sditf_get_ctrl,
1014
+};
1015
+
1016
+static int sditf_notifier_bound(struct v4l2_async_notifier *notifier,
1017
+ struct v4l2_subdev *subdev,
1018
+ struct v4l2_async_subdev *asd)
1019
+{
1020
+ struct sditf_priv *sditf = container_of(notifier,
1021
+ struct sditf_priv, notifier);
1022
+ struct media_entity *source_entity, *sink_entity;
1023
+ int ret = 0;
1024
+
1025
+ sditf->sensor_sd = subdev;
1026
+
1027
+ if (sditf->num_sensors == 1) {
1028
+ v4l2_err(subdev,
1029
+ "%s: the num of subdev is beyond %d\n",
1030
+ __func__, sditf->num_sensors);
1031
+ return -EBUSY;
1032
+ }
1033
+
1034
+ if (sditf->sd.entity.pads[0].flags & MEDIA_PAD_FL_SINK) {
1035
+ source_entity = &subdev->entity;
1036
+ sink_entity = &sditf->sd.entity;
1037
+
1038
+ ret = media_create_pad_link(source_entity,
1039
+ 0,
1040
+ sink_entity,
1041
+ 0,
1042
+ MEDIA_LNK_FL_ENABLED);
1043
+ if (ret)
1044
+ v4l2_err(&sditf->sd, "failed to create link for %s\n",
1045
+ sditf->sensor_sd->name);
1046
+ }
1047
+ sditf->sensor_sd = subdev;
1048
+ ++sditf->num_sensors;
1049
+
1050
+ v4l2_err(subdev, "Async registered subdev\n");
1051
+
1052
+ return 0;
1053
+}
1054
+
1055
+static void sditf_notifier_unbind(struct v4l2_async_notifier *notifier,
1056
+ struct v4l2_subdev *sd,
1057
+ struct v4l2_async_subdev *asd)
1058
+{
1059
+ struct sditf_priv *sditf = container_of(notifier,
1060
+ struct sditf_priv,
1061
+ notifier);
1062
+
1063
+ sditf->sensor_sd = NULL;
1064
+}
1065
+
1066
+static const struct v4l2_async_notifier_operations sditf_notifier_ops = {
1067
+ .bound = sditf_notifier_bound,
1068
+ .unbind = sditf_notifier_unbind,
1069
+};
1070
+
1071
+static int sditf_subdev_notifier(struct sditf_priv *sditf)
1072
+{
1073
+ struct v4l2_async_notifier *ntf = &sditf->notifier;
1074
+ int ret;
1075
+
1076
+ v4l2_async_notifier_init(ntf);
1077
+
1078
+ ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
1079
+ sditf->dev, &sditf->notifier,
1080
+ sizeof(struct sensor_async_subdev), 0,
1081
+ sditf_fwnode_parse);
1082
+ if (ret < 0)
1083
+ return ret;
1084
+
1085
+ sditf->sd.subdev_notifier = &sditf->notifier;
1086
+ sditf->notifier.ops = &sditf_notifier_ops;
1087
+
1088
+ ret = v4l2_async_subdev_notifier_register(&sditf->sd, &sditf->notifier);
1089
+ if (ret) {
1090
+ v4l2_err(&sditf->sd,
1091
+ "failed to register async notifier : %d\n",
1092
+ ret);
1093
+ v4l2_async_notifier_cleanup(&sditf->notifier);
1094
+ return ret;
1095
+ }
1096
+
1097
+ return v4l2_async_register_subdev(&sditf->sd);
1951098 }
1961099
1971100 static int rkcif_subdev_media_init(struct sditf_priv *priv)
1981101 {
1991102 struct rkcif_device *cif_dev = priv->cif_dev;
1103
+ struct v4l2_ctrl_handler *handler = &priv->ctrl_handler;
1104
+ unsigned long flags = V4L2_CTRL_FLAG_VOLATILE;
2001105 int ret;
1106
+ int pad_num = 0;
2011107
202
- priv->pads.flags = MEDIA_PAD_FL_SOURCE;
1108
+ if (priv->is_combine_mode) {
1109
+ priv->pads[0].flags = MEDIA_PAD_FL_SINK;
1110
+ priv->pads[1].flags = MEDIA_PAD_FL_SOURCE;
1111
+ pad_num = 2;
1112
+ } else {
1113
+ priv->pads[0].flags = MEDIA_PAD_FL_SOURCE;
1114
+ pad_num = 1;
1115
+ }
2031116 priv->sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_COMPOSER;
204
- ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pads);
1117
+ ret = media_entity_pads_init(&priv->sd.entity, pad_num, priv->pads);
2051118 if (ret < 0)
2061119 return ret;
2071120
208
- strncpy(priv->sd.name, dev_name(cif_dev->dev), sizeof(priv->sd.name));
1121
+ ret = v4l2_ctrl_handler_init(handler, 1);
1122
+ if (ret)
1123
+ return ret;
1124
+ priv->pixel_rate = v4l2_ctrl_new_std(handler, &rkcif_sditf_ctrl_ops,
1125
+ V4L2_CID_PIXEL_RATE,
1126
+ 0, SDITF_PIXEL_RATE_MAX,
1127
+ 1, SDITF_PIXEL_RATE_MAX);
1128
+ if (priv->pixel_rate)
1129
+ priv->pixel_rate->flags |= flags;
1130
+ priv->sd.ctrl_handler = handler;
1131
+ if (handler->error) {
1132
+ v4l2_ctrl_handler_free(handler);
1133
+ return handler->error;
1134
+ }
2091135
1136
+ strncpy(priv->sd.name, dev_name(cif_dev->dev), sizeof(priv->sd.name));
1137
+ priv->cap_info.width = 0;
1138
+ priv->cap_info.height = 0;
1139
+ priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
1140
+ priv->toisp_inf.link_mode = TOISP_NONE;
1141
+ priv->toisp_inf.ch_info[0].is_valid = false;
1142
+ priv->toisp_inf.ch_info[1].is_valid = false;
1143
+ priv->toisp_inf.ch_info[2].is_valid = false;
1144
+ if (priv->is_combine_mode)
1145
+ sditf_subdev_notifier(priv);
1146
+ atomic_set(&priv->power_cnt, 0);
1147
+ atomic_set(&priv->stream_cnt, 0);
1148
+ INIT_WORK(&priv->buffree_work.work, sditf_buffree_work);
1149
+ INIT_LIST_HEAD(&priv->buf_free_list);
2101150 return 0;
2111151 }
2121152
....@@ -215,6 +1155,7 @@
2151155 struct device *dev = &pdev->dev;
2161156 struct v4l2_subdev *sd;
2171157 struct sditf_priv *priv;
1158
+ struct device_node *node = dev->of_node;
2181159 int ret;
2191160
2201161 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
....@@ -230,7 +1171,19 @@
2301171
2311172 platform_set_drvdata(pdev, &sd->entity);
2321173
233
- rkcif_sditf_attach_cifdev(priv);
1174
+ ret = rkcif_sditf_attach_cifdev(priv);
1175
+ if (ret < 0)
1176
+ return ret;
1177
+
1178
+ ret = of_property_read_u32(node,
1179
+ "rockchip,combine-index",
1180
+ &priv->combine_index);
1181
+ if (ret) {
1182
+ priv->is_combine_mode = false;
1183
+ priv->combine_index = 0;
1184
+ } else {
1185
+ priv->is_combine_mode = true;
1186
+ }
2341187 ret = rkcif_subdev_media_init(priv);
2351188 if (ret < 0)
2361189 return ret;
....@@ -250,21 +1203,6 @@
2501203 return 0;
2511204 }
2521205
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
-
2681206 static const struct of_device_id rkcif_subdev_match_id[] = {
2691207 {
2701208 .compatible = "rockchip,rkcif-sditf",
....@@ -278,7 +1216,6 @@
2781216 .remove = rkcif_subdev_remove,
2791217 .driver = {
2801218 .name = "rkcif_sditf",
281
- .pm = &rkcif_subdev_pm_ops,
2821219 .of_match_table = rkcif_subdev_match_id,
2831220 },
2841221 };