hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
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], cif_dev->stream[0].rx_buf_num);
287
+ rkcif_free_rx_buf(&cif_dev->stream[1], cif_dev->stream[1].rx_buf_num);
288
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
289
+ rkcif_free_rx_buf(&cif_dev->stream[0], cif_dev->stream[0].rx_buf_num);
290
+ rkcif_free_rx_buf(&cif_dev->stream[1], cif_dev->stream[1].rx_buf_num);
291
+ rkcif_free_rx_buf(&cif_dev->stream[2], cif_dev->stream[2].rx_buf_num);
292
+ } else {
293
+ rkcif_free_rx_buf(&cif_dev->stream[0], cif_dev->stream[0].rx_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,90 @@
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
+
330
+static void sditf_channel_disable(struct sditf_priv *priv, int user);
105331 static long sditf_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
106332 {
107333 struct sditf_priv *priv = to_sditf_priv(sd);
334
+ struct rkisp_vicap_mode *mode;
335
+ struct v4l2_subdev_format fmt;
108336 struct rkcif_device *cif_dev = priv->cif_dev;
109337 struct v4l2_subdev *sensor_sd;
338
+ int *pbuf_num = NULL;
339
+ int ret = 0;
340
+ int *on = NULL;
110341
111
- if (!cif_dev->terminal_sensor.sd)
112
- rkcif_update_sensor_info(&cif_dev->stream[0]);
342
+ switch (cmd) {
343
+ case RKISP_VICAP_CMD_MODE:
344
+ mode = (struct rkisp_vicap_mode *)arg;
345
+ mutex_lock(&cif_dev->stream_lock);
346
+ memcpy(&priv->mode, mode, sizeof(*mode));
347
+ mutex_unlock(&cif_dev->stream_lock);
348
+ sditf_reinit_mode(priv, &priv->mode);
349
+ if (priv->is_combine_mode)
350
+ mode->input.merge_num = cif_dev->sditf_cnt;
351
+ else
352
+ mode->input.merge_num = 1;
353
+ mode->input.index = priv->combine_index;
354
+ return 0;
355
+ case RKISP_VICAP_CMD_INIT_BUF:
356
+ pbuf_num = (int *)arg;
357
+ priv->buf_num = *pbuf_num;
358
+ sditf_get_set_fmt(&priv->sd, NULL, &fmt);
359
+ ret = sditf_init_buf(priv);
360
+ return ret;
361
+ case RKMODULE_GET_HDR_CFG:
362
+ if (!cif_dev->terminal_sensor.sd)
363
+ rkcif_update_sensor_info(&cif_dev->stream[0]);
113364
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);
365
+ if (cif_dev->terminal_sensor.sd) {
366
+ sensor_sd = cif_dev->terminal_sensor.sd;
367
+ return v4l2_subdev_call(sensor_sd, core, ioctl, cmd, arg);
368
+ }
369
+ break;
370
+ case RKISP_VICAP_CMD_QUICK_STREAM:
371
+ on = (int *)arg;
372
+ if (*on) {
373
+ rkcif_stream_resume(cif_dev, RKCIF_RESUME_ISP);
374
+ } else {
375
+ if (priv->toisp_inf.link_mode == TOISP0) {
376
+ sditf_channel_disable(priv, 0);
377
+ } else if (priv->toisp_inf.link_mode == TOISP1) {
378
+ sditf_channel_disable(priv, 1);
379
+ } else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
380
+ sditf_channel_disable(priv, 0);
381
+ sditf_channel_disable(priv, 1);
382
+ }
383
+ rkcif_stream_suspend(cif_dev, RKCIF_RESUME_ISP);
384
+ }
385
+ break;
386
+ case RKISP_VICAP_CMD_SET_RESET:
387
+ if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
388
+ cif_dev->is_toisp_reset = true;
389
+ return 0;
390
+ }
391
+ break;
392
+ default:
393
+ break;
117394 }
118395
119396 return -EINVAL;
....@@ -123,9 +400,58 @@
123400 static long sditf_compat_ioctl32(struct v4l2_subdev *sd,
124401 unsigned int cmd, unsigned long arg)
125402 {
403
+ void __user *up = compat_ptr(arg);
126404 struct sditf_priv *priv = to_sditf_priv(sd);
127405 struct rkcif_device *cif_dev = priv->cif_dev;
128406 struct v4l2_subdev *sensor_sd;
407
+ struct rkisp_vicap_mode *mode;
408
+ struct rkmodule_hdr_cfg *hdr_cfg;
409
+ int buf_num;
410
+ int ret = 0;
411
+ int on;
412
+
413
+ switch (cmd) {
414
+ case RKISP_VICAP_CMD_MODE:
415
+ mode = kzalloc(sizeof(*mode), GFP_KERNEL);
416
+ if (!mode) {
417
+ ret = -ENOMEM;
418
+ return ret;
419
+ }
420
+ if (copy_from_user(mode, up, sizeof(*mode))) {
421
+ kfree(mode);
422
+ return -EFAULT;
423
+ }
424
+ ret = sditf_ioctl(sd, cmd, mode);
425
+ kfree(mode);
426
+ return ret;
427
+ case RKISP_VICAP_CMD_INIT_BUF:
428
+ if (copy_from_user(&buf_num, up, sizeof(int)))
429
+ return -EFAULT;
430
+ ret = sditf_ioctl(sd, cmd, &buf_num);
431
+ return ret;
432
+ case RKMODULE_GET_HDR_CFG:
433
+ hdr_cfg = kzalloc(sizeof(*hdr_cfg), GFP_KERNEL);
434
+ if (!hdr_cfg) {
435
+ ret = -ENOMEM;
436
+ return ret;
437
+ }
438
+ if (copy_from_user(hdr_cfg, up, sizeof(*hdr_cfg))) {
439
+ kfree(hdr_cfg);
440
+ return -EFAULT;
441
+ }
442
+ ret = sditf_ioctl(sd, cmd, hdr_cfg);
443
+ return ret;
444
+ case RKISP_VICAP_CMD_QUICK_STREAM:
445
+ if (copy_from_user(&on, up, sizeof(int)))
446
+ return -EFAULT;
447
+ ret = sditf_ioctl(sd, cmd, &on);
448
+ return ret;
449
+ case RKISP_VICAP_CMD_SET_RESET:
450
+ ret = sditf_ioctl(sd, cmd, NULL);
451
+ return ret;
452
+ default:
453
+ break;
454
+ }
129455
130456 if (!cif_dev->terminal_sensor.sd)
131457 rkcif_update_sensor_info(&cif_dev->stream[0]);
....@@ -139,15 +465,521 @@
139465 }
140466 #endif
141467
468
+static int sditf_channel_enable(struct sditf_priv *priv, int user)
469
+{
470
+ struct rkcif_device *cif_dev = priv->cif_dev;
471
+ struct rkmodule_capture_info *capture_info = &cif_dev->channels[0].capture_info;
472
+ unsigned int ch0 = 0, ch1 = 0, ch2 = 0;
473
+ unsigned int ctrl_val = 0;
474
+ unsigned int int_en = 0;
475
+ unsigned int offset_x = 0;
476
+ unsigned int offset_y = 0;
477
+ unsigned int width = priv->cap_info.width;
478
+ unsigned int height = priv->cap_info.height;
479
+ int csi_idx = cif_dev->csi_host_idx;
480
+
481
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE &&
482
+ priv->toisp_inf.link_mode == TOISP_UNITE) {
483
+ if (capture_info->multi_dev.dev_num != 2 ||
484
+ capture_info->multi_dev.pixel_offset != RKMOUDLE_UNITE_EXTEND_PIXEL) {
485
+ v4l2_err(&cif_dev->v4l2_dev,
486
+ "param error of online mode, combine dev num %d, offset %d\n",
487
+ capture_info->multi_dev.dev_num,
488
+ capture_info->multi_dev.pixel_offset);
489
+ return -EINVAL;
490
+ }
491
+ csi_idx = capture_info->multi_dev.dev_idx[user];
492
+ }
493
+
494
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
495
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
496
+ if (cif_dev->inf_id == RKCIF_MIPI_LVDS)
497
+ ch0 = csi_idx * 4;
498
+ else
499
+ ch0 = 24;//dvp
500
+ ctrl_val = (ch0 << 3) | 0x1;
501
+ if (user == 0)
502
+ int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FE(0);
503
+ else
504
+ int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FE(0);
505
+ priv->toisp_inf.ch_info[0].is_valid = true;
506
+ priv->toisp_inf.ch_info[0].id = ch0;
507
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
508
+ ch0 = cif_dev->csi_host_idx * 4 + 1;
509
+ ch1 = cif_dev->csi_host_idx * 4;
510
+ ctrl_val = (ch0 << 3) | 0x1;
511
+ ctrl_val |= (ch1 << 11) | 0x100;
512
+ if (user == 0)
513
+ int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1) |
514
+ CIF_TOISP0_FE(0) | CIF_TOISP0_FE(1);
515
+ else
516
+ int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1) |
517
+ CIF_TOISP1_FE(0) | CIF_TOISP1_FE(1);
518
+ priv->toisp_inf.ch_info[0].is_valid = true;
519
+ priv->toisp_inf.ch_info[0].id = ch0;
520
+ priv->toisp_inf.ch_info[1].is_valid = true;
521
+ priv->toisp_inf.ch_info[1].id = ch1;
522
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
523
+ ch0 = cif_dev->csi_host_idx * 4 + 2;
524
+ ch1 = cif_dev->csi_host_idx * 4 + 1;
525
+ ch2 = cif_dev->csi_host_idx * 4;
526
+ ctrl_val = (ch0 << 3) | 0x1;
527
+ ctrl_val |= (ch1 << 11) | 0x100;
528
+ ctrl_val |= (ch2 << 19) | 0x10000;
529
+ if (user == 0)
530
+ int_en = CIF_TOISP0_FS(0) | CIF_TOISP0_FS(1) | CIF_TOISP0_FS(2) |
531
+ CIF_TOISP0_FE(0) | CIF_TOISP0_FE(1) | CIF_TOISP0_FE(2);
532
+ else
533
+ int_en = CIF_TOISP1_FS(0) | CIF_TOISP1_FS(1) | CIF_TOISP1_FS(2) |
534
+ CIF_TOISP1_FE(0) | CIF_TOISP1_FE(1) | CIF_TOISP1_FE(2);
535
+ priv->toisp_inf.ch_info[0].is_valid = true;
536
+ priv->toisp_inf.ch_info[0].id = ch0;
537
+ priv->toisp_inf.ch_info[1].is_valid = true;
538
+ priv->toisp_inf.ch_info[1].id = ch1;
539
+ priv->toisp_inf.ch_info[2].is_valid = true;
540
+ priv->toisp_inf.ch_info[2].id = ch2;
541
+ }
542
+ if (user == 0) {
543
+ if (priv->toisp_inf.link_mode == TOISP_UNITE)
544
+ width = priv->cap_info.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
545
+ rkcif_write_register(cif_dev, CIF_REG_TOISP0_CTRL, ctrl_val);
546
+ if (width && height) {
547
+ rkcif_write_register(cif_dev, CIF_REG_TOISP0_CROP,
548
+ offset_x | (offset_y << 16));
549
+ rkcif_write_register(cif_dev, CIF_REG_TOISP0_SIZE,
550
+ width | (height << 16));
551
+ } else {
552
+ return -EINVAL;
553
+ }
554
+ } else {
555
+ if (priv->toisp_inf.link_mode == TOISP_UNITE) {
556
+ if (capture_info->mode == RKMODULE_MULTI_DEV_COMBINE_ONE)
557
+ offset_x = 0;
558
+ else
559
+ offset_x = priv->cap_info.width / 2 - RKMOUDLE_UNITE_EXTEND_PIXEL;
560
+ width = priv->cap_info.width / 2 + RKMOUDLE_UNITE_EXTEND_PIXEL;
561
+ }
562
+ rkcif_write_register(cif_dev, CIF_REG_TOISP1_CTRL, ctrl_val);
563
+ if (width && height) {
564
+ rkcif_write_register(cif_dev, CIF_REG_TOISP1_CROP,
565
+ offset_x | (offset_y << 16));
566
+ rkcif_write_register(cif_dev, CIF_REG_TOISP1_SIZE,
567
+ width | (height << 16));
568
+ } else {
569
+ return -EINVAL;
570
+ }
571
+ }
572
+#if IS_ENABLED(CONFIG_CPU_RV1106)
573
+ rv1106_sdmmc_get_lock();
574
+#endif
575
+ rkcif_write_register_or(cif_dev, CIF_REG_GLB_INTEN, int_en);
576
+#if IS_ENABLED(CONFIG_CPU_RV1106)
577
+ rv1106_sdmmc_put_lock();
578
+#endif
579
+ return 0;
580
+}
581
+
582
+static void sditf_channel_disable(struct sditf_priv *priv, int user)
583
+{
584
+ struct rkcif_device *cif_dev = priv->cif_dev;
585
+ unsigned int ctrl_val = 0;
586
+
587
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
588
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
589
+ if (user == 0)
590
+ ctrl_val = CIF_TOISP0_FE(0);
591
+ else
592
+ ctrl_val = CIF_TOISP1_FE(0);
593
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
594
+ if (user == 0)
595
+ ctrl_val = CIF_TOISP0_FE(0) | CIF_TOISP0_FE(1);
596
+ else
597
+ ctrl_val = CIF_TOISP1_FE(0) | CIF_TOISP1_FE(1);
598
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
599
+ if (user == 0)
600
+ ctrl_val = CIF_TOISP0_FE(0) | CIF_TOISP0_FE(1) | CIF_TOISP0_FE(2);
601
+ else
602
+ ctrl_val = CIF_TOISP1_FE(0) | CIF_TOISP1_FE(1) | CIF_TOISP1_FE(2);
603
+ }
604
+#if IS_ENABLED(CONFIG_CPU_RV1106)
605
+ rv1106_sdmmc_get_lock();
606
+#endif
607
+ rkcif_write_register_or(cif_dev, CIF_REG_GLB_INTEN, ctrl_val);
608
+#if IS_ENABLED(CONFIG_CPU_RV1106)
609
+ rv1106_sdmmc_put_lock();
610
+#endif
611
+ priv->toisp_inf.ch_info[0].is_valid = false;
612
+ priv->toisp_inf.ch_info[1].is_valid = false;
613
+ priv->toisp_inf.ch_info[2].is_valid = false;
614
+}
615
+
616
+void sditf_change_to_online(struct sditf_priv *priv)
617
+{
618
+ struct rkcif_device *cif_dev = priv->cif_dev;
619
+
620
+ priv->mode.rdbk_mode = RKISP_VICAP_ONLINE;
621
+ if (priv->toisp_inf.link_mode == TOISP0) {
622
+ sditf_channel_enable(priv, 0);
623
+ } else if (priv->toisp_inf.link_mode == TOISP1) {
624
+ sditf_channel_enable(priv, 1);
625
+ } else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
626
+ sditf_channel_enable(priv, 0);
627
+ sditf_channel_enable(priv, 1);
628
+ }
629
+
630
+ if (cif_dev->is_thunderboot) {
631
+ if (priv->hdr_cfg.hdr_mode == NO_HDR) {
632
+ rkcif_free_rx_buf(&cif_dev->stream[0], cif_dev->stream[0].rx_buf_num);
633
+ cif_dev->stream[0].is_line_wake_up = false;
634
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
635
+ rkcif_free_rx_buf(&cif_dev->stream[1], cif_dev->stream[1].rx_buf_num);
636
+ cif_dev->stream[0].is_line_wake_up = false;
637
+ cif_dev->stream[1].is_line_wake_up = false;
638
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
639
+ rkcif_free_rx_buf(&cif_dev->stream[2], cif_dev->stream[2].rx_buf_num);
640
+ cif_dev->stream[0].is_line_wake_up = false;
641
+ cif_dev->stream[1].is_line_wake_up = false;
642
+ cif_dev->stream[2].is_line_wake_up = false;
643
+ }
644
+ cif_dev->wait_line_cache = 0;
645
+ cif_dev->wait_line = 0;
646
+ cif_dev->wait_line_bak = 0;
647
+ cif_dev->is_thunderboot = false;
648
+ }
649
+}
650
+
651
+void sditf_disable_immediately(struct sditf_priv *priv)
652
+{
653
+ struct rkcif_device *cif_dev = priv->cif_dev;
654
+ u32 ctrl_val = 0x10101;
655
+
656
+ if (priv->toisp_inf.link_mode == TOISP0) {
657
+ rkcif_write_register_and(cif_dev, CIF_REG_TOISP0_CTRL, ~ctrl_val);
658
+ } else if (priv->toisp_inf.link_mode == TOISP1) {
659
+ rkcif_write_register_and(cif_dev, CIF_REG_TOISP1_CTRL, ~ctrl_val);
660
+ } else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
661
+ rkcif_write_register_and(cif_dev, CIF_REG_TOISP0_CTRL, ~ctrl_val);
662
+ rkcif_write_register_and(cif_dev, CIF_REG_TOISP1_CTRL, ~ctrl_val);
663
+ }
664
+}
665
+
666
+static void sditf_check_capture_mode(struct rkcif_device *cif_dev)
667
+{
668
+ struct rkcif_device *dev = NULL;
669
+ int i = 0;
670
+ int toisp_cnt = 0;
671
+
672
+ for (i = 0; i < cif_dev->hw_dev->dev_num; i++) {
673
+ dev = cif_dev->hw_dev->cif_dev[i];
674
+ if (dev && dev->sditf_cnt)
675
+ toisp_cnt++;
676
+ }
677
+ if (cif_dev->is_thunderboot && toisp_cnt == 1)
678
+ cif_dev->is_rdbk_to_online = true;
679
+ else
680
+ cif_dev->is_rdbk_to_online = false;
681
+}
682
+
683
+static int sditf_start_stream(struct sditf_priv *priv)
684
+{
685
+ struct rkcif_device *cif_dev = priv->cif_dev;
686
+ struct v4l2_subdev_format fmt;
687
+ unsigned int mode = RKCIF_STREAM_MODE_TOISP;
688
+
689
+ sditf_check_capture_mode(cif_dev);
690
+ sditf_get_set_fmt(&priv->sd, NULL, &fmt);
691
+ if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE) {
692
+ if (priv->toisp_inf.link_mode == TOISP0) {
693
+ sditf_channel_enable(priv, 0);
694
+ } else if (priv->toisp_inf.link_mode == TOISP1) {
695
+ sditf_channel_enable(priv, 1);
696
+ } else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
697
+ sditf_channel_enable(priv, 0);
698
+ sditf_channel_enable(priv, 1);
699
+ }
700
+ mode = RKCIF_STREAM_MODE_TOISP;
701
+ } else if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO) {
702
+ mode = RKCIF_STREAM_MODE_TOISP_RDBK;
703
+ }
704
+
705
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
706
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
707
+ rkcif_do_start_stream(&cif_dev->stream[0], mode);
708
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
709
+ rkcif_do_start_stream(&cif_dev->stream[0], mode);
710
+ rkcif_do_start_stream(&cif_dev->stream[1], mode);
711
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
712
+ rkcif_do_start_stream(&cif_dev->stream[0], mode);
713
+ rkcif_do_start_stream(&cif_dev->stream[1], mode);
714
+ rkcif_do_start_stream(&cif_dev->stream[2], mode);
715
+ }
716
+ INIT_LIST_HEAD(&priv->buf_free_list);
717
+ return 0;
718
+}
719
+
720
+static int sditf_stop_stream(struct sditf_priv *priv)
721
+{
722
+ struct rkcif_device *cif_dev = priv->cif_dev;
723
+ unsigned int mode = RKCIF_STREAM_MODE_TOISP;
724
+
725
+ if (priv->toisp_inf.link_mode == TOISP0) {
726
+ sditf_channel_disable(priv, 0);
727
+ } else if (priv->toisp_inf.link_mode == TOISP1) {
728
+ sditf_channel_disable(priv, 1);
729
+ } else if (priv->toisp_inf.link_mode == TOISP_UNITE) {
730
+ sditf_channel_disable(priv, 0);
731
+ sditf_channel_disable(priv, 1);
732
+ }
733
+
734
+ if (priv->mode.rdbk_mode == RKISP_VICAP_ONLINE)
735
+ mode = RKCIF_STREAM_MODE_TOISP;
736
+ else if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AUTO)
737
+ mode = RKCIF_STREAM_MODE_TOISP_RDBK;
738
+
739
+ if (priv->hdr_cfg.hdr_mode == NO_HDR ||
740
+ priv->hdr_cfg.hdr_mode == HDR_COMPR) {
741
+ rkcif_do_stop_stream(&cif_dev->stream[0], mode);
742
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X2) {
743
+ rkcif_do_stop_stream(&cif_dev->stream[0], mode);
744
+ rkcif_do_stop_stream(&cif_dev->stream[1], mode);
745
+ } else if (priv->hdr_cfg.hdr_mode == HDR_X3) {
746
+ rkcif_do_stop_stream(&cif_dev->stream[0], mode);
747
+ rkcif_do_stop_stream(&cif_dev->stream[1], mode);
748
+ rkcif_do_stop_stream(&cif_dev->stream[2], mode);
749
+ }
750
+ return 0;
751
+}
752
+
753
+static int sditf_s_stream(struct v4l2_subdev *sd, int on)
754
+{
755
+ struct sditf_priv *priv = to_sditf_priv(sd);
756
+ struct rkcif_device *cif_dev = priv->cif_dev;
757
+ int ret = 0;
758
+
759
+ if (!on && atomic_dec_return(&priv->stream_cnt))
760
+ return 0;
761
+
762
+ if (on && atomic_inc_return(&priv->stream_cnt) > 1)
763
+ return 0;
764
+
765
+ if (cif_dev->chip_id >= CHIP_RK3588_CIF) {
766
+ if (priv->mode.rdbk_mode == RKISP_VICAP_RDBK_AIQ)
767
+ return 0;
768
+ v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
769
+ "%s, toisp mode %d, hdr %d, stream on %d\n",
770
+ __func__, priv->toisp_inf.link_mode, priv->hdr_cfg.hdr_mode, on);
771
+ if (on) {
772
+ ret = sditf_start_stream(priv);
773
+ } else {
774
+ ret = sditf_stop_stream(priv);
775
+ sditf_free_buf(priv);
776
+ priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
777
+ }
778
+
779
+ }
780
+ if (on && ret)
781
+ atomic_dec(&priv->stream_cnt);
782
+ return ret;
783
+}
784
+
785
+static int sditf_s_power(struct v4l2_subdev *sd, int on)
786
+{
787
+ struct sditf_priv *priv = to_sditf_priv(sd);
788
+ struct rkcif_device *cif_dev = priv->cif_dev;
789
+ struct rkcif_vdev_node *node = &cif_dev->stream[0].vnode;
790
+ int ret = 0;
791
+
792
+ if (!on && atomic_dec_return(&priv->power_cnt))
793
+ return 0;
794
+
795
+ if (on && atomic_inc_return(&priv->power_cnt) > 1)
796
+ return 0;
797
+
798
+ if (cif_dev->chip_id >= CHIP_RK3588_CIF) {
799
+ v4l2_dbg(1, rkcif_debug, &cif_dev->v4l2_dev,
800
+ "%s, toisp mode %d, hdr %d, set power %d\n",
801
+ __func__, priv->toisp_inf.link_mode, priv->hdr_cfg.hdr_mode, on);
802
+ mutex_lock(&cif_dev->stream_lock);
803
+ if (on) {
804
+ ret = pm_runtime_resume_and_get(cif_dev->dev);
805
+ ret |= v4l2_pipeline_pm_get(&node->vdev.entity);
806
+ } else {
807
+ v4l2_pipeline_pm_put(&node->vdev.entity);
808
+ pm_runtime_put_sync(cif_dev->dev);
809
+ priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
810
+ }
811
+ v4l2_info(&node->vdev, "s_power %d, entity use_count %d\n",
812
+ on, node->vdev.entity.use_count);
813
+ mutex_unlock(&cif_dev->stream_lock);
814
+ }
815
+ return ret;
816
+}
817
+
818
+static int sditf_s_rx_buffer(struct v4l2_subdev *sd,
819
+ void *buf, unsigned int *size)
820
+{
821
+ struct sditf_priv *priv = to_sditf_priv(sd);
822
+ struct rkcif_device *cif_dev = priv->cif_dev;
823
+ struct rkcif_sensor_info *sensor = &cif_dev->terminal_sensor;
824
+ struct rkcif_stream *stream = NULL;
825
+ struct rkisp_rx_buf *dbufs;
826
+ struct rkcif_rx_buffer *rx_buf = NULL;
827
+ unsigned long flags, buffree_flags;
828
+ u32 diff_time = 1000000;
829
+ u32 early_time = 0;
830
+ bool is_free = false;
831
+
832
+ if (!buf) {
833
+ v4l2_err(&cif_dev->v4l2_dev, "buf is NULL\n");
834
+ return -EINVAL;
835
+ }
836
+
837
+ dbufs = buf;
838
+ if (cif_dev->hdr.hdr_mode == NO_HDR) {
839
+ if (dbufs->type == BUF_SHORT)
840
+ stream = &cif_dev->stream[0];
841
+ else
842
+ return -EINVAL;
843
+ } else if (cif_dev->hdr.hdr_mode == HDR_X2) {
844
+ if (dbufs->type == BUF_SHORT)
845
+ stream = &cif_dev->stream[1];
846
+ else if (dbufs->type == BUF_MIDDLE)
847
+ stream = &cif_dev->stream[0];
848
+ else
849
+ return -EINVAL;
850
+ } else if (cif_dev->hdr.hdr_mode == HDR_X3) {
851
+ if (dbufs->type == BUF_SHORT)
852
+ stream = &cif_dev->stream[2];
853
+ else if (dbufs->type == BUF_MIDDLE)
854
+ stream = &cif_dev->stream[1];
855
+ else if (dbufs->type == BUF_LONG)
856
+ stream = &cif_dev->stream[0];
857
+ else
858
+ return -EINVAL;
859
+ }
860
+
861
+ if (!stream)
862
+ return -EINVAL;
863
+
864
+ rx_buf = to_cif_rx_buf(dbufs);
865
+ v4l2_dbg(3, rkcif_debug, &cif_dev->v4l2_dev, "buf back to vicap 0x%x\n",
866
+ (u32)rx_buf->dummy.dma_addr);
867
+ spin_lock_irqsave(&stream->vbq_lock, flags);
868
+ stream->last_rx_buf_idx = dbufs->sequence + 1;
869
+ atomic_inc(&stream->buf_cnt);
870
+
871
+ if (!list_empty(&stream->rx_buf_head) &&
872
+ cif_dev->is_thunderboot &&
873
+ (!cif_dev->is_rtt_suspend) &&
874
+ (dbufs->type == BUF_SHORT ||
875
+ (dbufs->type != BUF_SHORT && (!dbufs->is_switch)))) {
876
+ spin_lock_irqsave(&cif_dev->buffree_lock, buffree_flags);
877
+ list_add_tail(&rx_buf->list_free, &priv->buf_free_list);
878
+ spin_unlock_irqrestore(&cif_dev->buffree_lock, buffree_flags);
879
+ atomic_dec(&stream->buf_cnt);
880
+ stream->total_buf_num--;
881
+ schedule_work(&priv->buffree_work.work);
882
+ is_free = true;
883
+ }
884
+
885
+ if (!is_free && (!dbufs->is_switch)) {
886
+ list_add_tail(&rx_buf->list, &stream->rx_buf_head);
887
+ if (cif_dev->resume_mode != RKISP_RTT_MODE_ONE_FRAME) {
888
+ rkcif_assign_check_buffer_update_toisp(stream);
889
+ if (!stream->dma_en) {
890
+ stream->to_en_dma = RKCIF_DMAEN_BY_ISP;
891
+ rkcif_enable_dma_capture(stream, true);
892
+ cif_dev->sensor_work.on = 1;
893
+ schedule_work(&cif_dev->sensor_work.work);
894
+ }
895
+ }
896
+ if (cif_dev->rdbk_debug) {
897
+ u32 offset = 0;
898
+
899
+ offset = rx_buf->dummy.size - stream->pixm.plane_fmt[0].bytesperline * 3;
900
+ memset(rx_buf->dummy.vaddr + offset,
901
+ 0x00, stream->pixm.plane_fmt[0].bytesperline * 3);
902
+ if (cif_dev->is_thunderboot)
903
+ dma_sync_single_for_device(cif_dev->dev,
904
+ rx_buf->dummy.dma_addr + rx_buf->dummy.size -
905
+ stream->pixm.plane_fmt[0].bytesperline * 3,
906
+ stream->pixm.plane_fmt[0].bytesperline * 3,
907
+ DMA_FROM_DEVICE);
908
+ else
909
+ cif_dev->hw_dev->mem_ops->prepare(rx_buf->dummy.mem_priv);
910
+ }
911
+ }
912
+
913
+ if (dbufs->is_switch && dbufs->type == BUF_SHORT) {
914
+ if (stream->is_in_vblank)
915
+ sditf_change_to_online(priv);
916
+ else
917
+ stream->is_change_toisp = true;
918
+ v4l2_dbg(3, rkcif_debug, &cif_dev->v4l2_dev,
919
+ "switch to online mode\n");
920
+ }
921
+ spin_unlock_irqrestore(&stream->vbq_lock, flags);
922
+
923
+ if (!cif_dev->is_thunderboot ||
924
+ cif_dev->is_rdbk_to_online == false)
925
+ return 0;
926
+
927
+ if (dbufs->runtime_us && cif_dev->early_line == 0) {
928
+ if (!cif_dev->sensor_linetime)
929
+ cif_dev->sensor_linetime = rkcif_get_linetime(stream);
930
+ cif_dev->isp_runtime_max = dbufs->runtime_us;
931
+ if (cif_dev->is_thunderboot)
932
+ diff_time = 200000;
933
+ else
934
+ diff_time = 1000000;
935
+ if (dbufs->runtime_us * 1000 + cif_dev->sensor_linetime > diff_time)
936
+ early_time = dbufs->runtime_us * 1000 - diff_time;
937
+ else
938
+ early_time = diff_time;
939
+ cif_dev->early_line = div_u64(early_time, cif_dev->sensor_linetime);
940
+ cif_dev->wait_line_cache = sensor->raw_rect.height - cif_dev->early_line;
941
+ if (cif_dev->rdbk_debug &&
942
+ dbufs->sequence < 15)
943
+ v4l2_info(&cif_dev->v4l2_dev,
944
+ "%s, isp runtime %d, line time %d, early_line %d, line_intr_cnt %d, seq %d, type %d, dma_addr %x\n",
945
+ __func__, dbufs->runtime_us, cif_dev->sensor_linetime,
946
+ cif_dev->early_line, cif_dev->wait_line_cache,
947
+ dbufs->sequence, dbufs->type, (u32)rx_buf->dummy.dma_addr);
948
+ } else {
949
+ if (dbufs->runtime_us < cif_dev->isp_runtime_max) {
950
+ cif_dev->isp_runtime_max = dbufs->runtime_us;
951
+ if (cif_dev->is_thunderboot)
952
+ diff_time = 200000;
953
+ else
954
+ diff_time = 1000000;
955
+ if (dbufs->runtime_us * 1000 + cif_dev->sensor_linetime > diff_time)
956
+ early_time = dbufs->runtime_us * 1000 - diff_time;
957
+ else
958
+ early_time = diff_time;
959
+ cif_dev->early_line = div_u64(early_time, cif_dev->sensor_linetime);
960
+ cif_dev->wait_line_cache = sensor->raw_rect.height - cif_dev->early_line;
961
+ }
962
+ if (cif_dev->rdbk_debug &&
963
+ dbufs->sequence < 15)
964
+ v4l2_info(&cif_dev->v4l2_dev,
965
+ "isp runtime %d, seq %d, type %d, early_line %d, dma addr %x\n",
966
+ dbufs->runtime_us, dbufs->sequence, dbufs->type,
967
+ cif_dev->early_line, (u32)rx_buf->dummy.dma_addr);
968
+ }
969
+ return 0;
970
+}
971
+
142972 static const struct v4l2_subdev_pad_ops sditf_subdev_pad_ops = {
143973 .set_fmt = sditf_get_set_fmt,
144974 .get_fmt = sditf_get_set_fmt,
145975 .get_selection = sditf_get_selection,
976
+ .get_mbus_config = sditf_g_mbus_config,
146977 };
147978
148979 static const struct v4l2_subdev_video_ops sditf_video_ops = {
149980 .g_frame_interval = sditf_g_frame_interval,
150
- .g_mbus_config = sditf_g_mbus_config,
981
+ .s_stream = sditf_s_stream,
982
+ .s_rx_buffer = sditf_s_rx_buffer,
151983 };
152984
153985 static const struct v4l2_subdev_core_ops sditf_core_ops = {
....@@ -155,6 +987,7 @@
155987 #ifdef CONFIG_COMPAT
156988 .compat_ioctl32 = sditf_compat_ioctl32,
157989 #endif
990
+ .s_power = sditf_s_power,
158991 };
159992
160993 static const struct v4l2_subdev_ops sditf_subdev_ops = {
....@@ -188,25 +1021,231 @@
1881021 return -EINVAL;
1891022 }
1901023
191
- cif_dev->sditf = sditf;
1024
+ cif_dev->sditf[cif_dev->sditf_cnt] = sditf;
1921025 sditf->cif_dev = cif_dev;
1026
+ cif_dev->sditf_cnt++;
1931027
1941028 return 0;
1029
+}
1030
+
1031
+struct sensor_async_subdev {
1032
+ struct v4l2_async_subdev asd;
1033
+ struct v4l2_mbus_config mbus;
1034
+ int lanes;
1035
+};
1036
+
1037
+static int sditf_fwnode_parse(struct device *dev,
1038
+ struct v4l2_fwnode_endpoint *vep,
1039
+ struct v4l2_async_subdev *asd)
1040
+{
1041
+ struct sensor_async_subdev *s_asd =
1042
+ container_of(asd, struct sensor_async_subdev, asd);
1043
+ struct v4l2_mbus_config *config = &s_asd->mbus;
1044
+
1045
+ if (vep->base.port != 0) {
1046
+ dev_err(dev, "sditf has only port 0\n");
1047
+ return -EINVAL;
1048
+ }
1049
+
1050
+ if (vep->bus_type == V4L2_MBUS_CSI2_DPHY ||
1051
+ vep->bus_type == V4L2_MBUS_CSI2_CPHY) {
1052
+ config->type = vep->bus_type;
1053
+ config->flags = vep->bus.mipi_csi2.flags;
1054
+ s_asd->lanes = vep->bus.mipi_csi2.num_data_lanes;
1055
+ } else if (vep->bus_type == V4L2_MBUS_CCP2) {
1056
+ config->type = vep->bus_type;
1057
+ s_asd->lanes = vep->bus.mipi_csi1.data_lane;
1058
+ } else {
1059
+ dev_err(dev, "type is not supported\n");
1060
+ return -EINVAL;
1061
+ }
1062
+
1063
+ switch (s_asd->lanes) {
1064
+ case 1:
1065
+ config->flags |= V4L2_MBUS_CSI2_1_LANE;
1066
+ break;
1067
+ case 2:
1068
+ config->flags |= V4L2_MBUS_CSI2_2_LANE;
1069
+ break;
1070
+ case 3:
1071
+ config->flags |= V4L2_MBUS_CSI2_3_LANE;
1072
+ break;
1073
+ case 4:
1074
+ config->flags |= V4L2_MBUS_CSI2_4_LANE;
1075
+ break;
1076
+ default:
1077
+ return -EINVAL;
1078
+ }
1079
+
1080
+ return 0;
1081
+}
1082
+
1083
+static int rkcif_sditf_get_ctrl(struct v4l2_ctrl *ctrl)
1084
+{
1085
+ struct sditf_priv *priv = container_of(ctrl->handler,
1086
+ struct sditf_priv,
1087
+ ctrl_handler);
1088
+ struct v4l2_ctrl *sensor_ctrl = NULL;
1089
+
1090
+ switch (ctrl->id) {
1091
+ case V4L2_CID_PIXEL_RATE:
1092
+ if (priv->cif_dev->terminal_sensor.sd) {
1093
+ sensor_ctrl = v4l2_ctrl_find(priv->cif_dev->terminal_sensor.sd->ctrl_handler, V4L2_CID_PIXEL_RATE);
1094
+ if (sensor_ctrl) {
1095
+ ctrl->val = v4l2_ctrl_g_ctrl_int64(sensor_ctrl);
1096
+ __v4l2_ctrl_s_ctrl_int64(priv->pixel_rate, ctrl->val);
1097
+ v4l2_dbg(1, rkcif_debug, &priv->cif_dev->v4l2_dev,
1098
+ "%s, %s pixel rate %d\n",
1099
+ __func__, priv->cif_dev->terminal_sensor.sd->name, ctrl->val);
1100
+ return 0;
1101
+ } else {
1102
+ return -EINVAL;
1103
+ }
1104
+ }
1105
+ return -EINVAL;
1106
+ default:
1107
+ return -EINVAL;
1108
+ }
1109
+}
1110
+
1111
+static const struct v4l2_ctrl_ops rkcif_sditf_ctrl_ops = {
1112
+ .g_volatile_ctrl = rkcif_sditf_get_ctrl,
1113
+};
1114
+
1115
+static int sditf_notifier_bound(struct v4l2_async_notifier *notifier,
1116
+ struct v4l2_subdev *subdev,
1117
+ struct v4l2_async_subdev *asd)
1118
+{
1119
+ struct sditf_priv *sditf = container_of(notifier,
1120
+ struct sditf_priv, notifier);
1121
+ struct media_entity *source_entity, *sink_entity;
1122
+ int ret = 0;
1123
+
1124
+ sditf->sensor_sd = subdev;
1125
+
1126
+ if (sditf->num_sensors == 1) {
1127
+ v4l2_err(subdev,
1128
+ "%s: the num of subdev is beyond %d\n",
1129
+ __func__, sditf->num_sensors);
1130
+ return -EBUSY;
1131
+ }
1132
+
1133
+ if (sditf->sd.entity.pads[0].flags & MEDIA_PAD_FL_SINK) {
1134
+ source_entity = &subdev->entity;
1135
+ sink_entity = &sditf->sd.entity;
1136
+
1137
+ ret = media_create_pad_link(source_entity,
1138
+ 0,
1139
+ sink_entity,
1140
+ 0,
1141
+ MEDIA_LNK_FL_ENABLED);
1142
+ if (ret)
1143
+ v4l2_err(&sditf->sd, "failed to create link for %s\n",
1144
+ sditf->sensor_sd->name);
1145
+ }
1146
+ sditf->sensor_sd = subdev;
1147
+ ++sditf->num_sensors;
1148
+
1149
+ v4l2_err(subdev, "Async registered subdev\n");
1150
+
1151
+ return 0;
1152
+}
1153
+
1154
+static void sditf_notifier_unbind(struct v4l2_async_notifier *notifier,
1155
+ struct v4l2_subdev *sd,
1156
+ struct v4l2_async_subdev *asd)
1157
+{
1158
+ struct sditf_priv *sditf = container_of(notifier,
1159
+ struct sditf_priv,
1160
+ notifier);
1161
+
1162
+ sditf->sensor_sd = NULL;
1163
+}
1164
+
1165
+static const struct v4l2_async_notifier_operations sditf_notifier_ops = {
1166
+ .bound = sditf_notifier_bound,
1167
+ .unbind = sditf_notifier_unbind,
1168
+};
1169
+
1170
+static int sditf_subdev_notifier(struct sditf_priv *sditf)
1171
+{
1172
+ struct v4l2_async_notifier *ntf = &sditf->notifier;
1173
+ int ret;
1174
+
1175
+ v4l2_async_notifier_init(ntf);
1176
+
1177
+ ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
1178
+ sditf->dev, &sditf->notifier,
1179
+ sizeof(struct sensor_async_subdev), 0,
1180
+ sditf_fwnode_parse);
1181
+ if (ret < 0)
1182
+ return ret;
1183
+
1184
+ sditf->sd.subdev_notifier = &sditf->notifier;
1185
+ sditf->notifier.ops = &sditf_notifier_ops;
1186
+
1187
+ ret = v4l2_async_subdev_notifier_register(&sditf->sd, &sditf->notifier);
1188
+ if (ret) {
1189
+ v4l2_err(&sditf->sd,
1190
+ "failed to register async notifier : %d\n",
1191
+ ret);
1192
+ v4l2_async_notifier_cleanup(&sditf->notifier);
1193
+ return ret;
1194
+ }
1195
+
1196
+ return v4l2_async_register_subdev(&sditf->sd);
1951197 }
1961198
1971199 static int rkcif_subdev_media_init(struct sditf_priv *priv)
1981200 {
1991201 struct rkcif_device *cif_dev = priv->cif_dev;
1202
+ struct v4l2_ctrl_handler *handler = &priv->ctrl_handler;
1203
+ unsigned long flags = V4L2_CTRL_FLAG_VOLATILE;
2001204 int ret;
1205
+ int pad_num = 0;
2011206
202
- priv->pads.flags = MEDIA_PAD_FL_SOURCE;
1207
+ if (priv->is_combine_mode) {
1208
+ priv->pads[0].flags = MEDIA_PAD_FL_SINK;
1209
+ priv->pads[1].flags = MEDIA_PAD_FL_SOURCE;
1210
+ pad_num = 2;
1211
+ } else {
1212
+ priv->pads[0].flags = MEDIA_PAD_FL_SOURCE;
1213
+ pad_num = 1;
1214
+ }
2031215 priv->sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_COMPOSER;
204
- ret = media_entity_pads_init(&priv->sd.entity, 1, &priv->pads);
1216
+ ret = media_entity_pads_init(&priv->sd.entity, pad_num, priv->pads);
2051217 if (ret < 0)
2061218 return ret;
2071219
208
- strncpy(priv->sd.name, dev_name(cif_dev->dev), sizeof(priv->sd.name));
1220
+ ret = v4l2_ctrl_handler_init(handler, 1);
1221
+ if (ret)
1222
+ return ret;
1223
+ priv->pixel_rate = v4l2_ctrl_new_std(handler, &rkcif_sditf_ctrl_ops,
1224
+ V4L2_CID_PIXEL_RATE,
1225
+ 0, SDITF_PIXEL_RATE_MAX,
1226
+ 1, SDITF_PIXEL_RATE_MAX);
1227
+ if (priv->pixel_rate)
1228
+ priv->pixel_rate->flags |= flags;
1229
+ priv->sd.ctrl_handler = handler;
1230
+ if (handler->error) {
1231
+ v4l2_ctrl_handler_free(handler);
1232
+ return handler->error;
1233
+ }
2091234
1235
+ strncpy(priv->sd.name, dev_name(cif_dev->dev), sizeof(priv->sd.name));
1236
+ priv->cap_info.width = 0;
1237
+ priv->cap_info.height = 0;
1238
+ priv->mode.rdbk_mode = RKISP_VICAP_RDBK_AIQ;
1239
+ priv->toisp_inf.link_mode = TOISP_NONE;
1240
+ priv->toisp_inf.ch_info[0].is_valid = false;
1241
+ priv->toisp_inf.ch_info[1].is_valid = false;
1242
+ priv->toisp_inf.ch_info[2].is_valid = false;
1243
+ if (priv->is_combine_mode)
1244
+ sditf_subdev_notifier(priv);
1245
+ atomic_set(&priv->power_cnt, 0);
1246
+ atomic_set(&priv->stream_cnt, 0);
1247
+ INIT_WORK(&priv->buffree_work.work, sditf_buffree_work);
1248
+ INIT_LIST_HEAD(&priv->buf_free_list);
2101249 return 0;
2111250 }
2121251
....@@ -215,6 +1254,7 @@
2151254 struct device *dev = &pdev->dev;
2161255 struct v4l2_subdev *sd;
2171256 struct sditf_priv *priv;
1257
+ struct device_node *node = dev->of_node;
2181258 int ret;
2191259
2201260 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
....@@ -230,7 +1270,19 @@
2301270
2311271 platform_set_drvdata(pdev, &sd->entity);
2321272
233
- rkcif_sditf_attach_cifdev(priv);
1273
+ ret = rkcif_sditf_attach_cifdev(priv);
1274
+ if (ret < 0)
1275
+ return ret;
1276
+
1277
+ ret = of_property_read_u32(node,
1278
+ "rockchip,combine-index",
1279
+ &priv->combine_index);
1280
+ if (ret) {
1281
+ priv->is_combine_mode = false;
1282
+ priv->combine_index = 0;
1283
+ } else {
1284
+ priv->is_combine_mode = true;
1285
+ }
2341286 ret = rkcif_subdev_media_init(priv);
2351287 if (ret < 0)
2361288 return ret;
....@@ -250,21 +1302,6 @@
2501302 return 0;
2511303 }
2521304
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
-
2681305 static const struct of_device_id rkcif_subdev_match_id[] = {
2691306 {
2701307 .compatible = "rockchip,rkcif-sditf",
....@@ -278,7 +1315,6 @@
2781315 .remove = rkcif_subdev_remove,
2791316 .driver = {
2801317 .name = "rkcif_sditf",
281
- .pm = &rkcif_subdev_pm_ops,
2821318 .of_match_table = rkcif_subdev_match_id,
2831319 },
2841320 };