1
2 /*
3 * vin_video.c for video api
4 *
5 * Copyright (c) 2017 by Allwinnertech Co., Ltd. http://www.allwinnertech.com
6 *
7 * Authors: Zhao Wei <zhaowei@allwinnertech.com>
8 * Yang Feng <yangfeng@allwinnertech.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15 #include <linux/version.h>
16 #include <linux/videodev2.h>
17 #include <linux/string.h>
18 #include <linux/freezer.h>
19 #include <linux/sort.h>
20 #include <linux/platform_device.h>
21 #include <linux/interrupt.h>
22 #include <linux/i2c.h>
23 #include <linux/moduleparam.h>
24 #include <media/v4l2-device.h>
25 #include <media/v4l2-ioctl.h>
26 #include <media/v4l2-common.h>
27 #include <media/v4l2-mediabus.h>
28 #include <media/v4l2-subdev.h>
29 #include <media/videobuf2-dma-contig.h>
30
31 #include <linux/regulator/consumer.h>
32 #ifdef CONFIG_DEVFREQ_DRAM_FREQ_WITH_SOFT_NOTIFY
33 #include <linux/sunxi_dramfreq.h>
34 #endif
35
36 #include "../utility/config.h"
37 #include "../modules/sensor/sensor_helper.h"
38 #include "../utility/vin_io.h"
39 #include "../vin-csi/sunxi_csi.h"
40 #include "../vin-isp/sunxi_isp.h"
41 #include "../vin-vipp/sunxi_scaler.h"
42 #include "../vin-mipi/sunxi_mipi.h"
43 #include "../vin.h"
44
45 #define VIN_MAJOR_VERSION 1
46 #define VIN_MINOR_VERSION 1
47 #define VIN_RELEASE 0
48
49 #define VIN_VERSION \
50 KERNEL_VERSION(VIN_MAJOR_VERSION, VIN_MINOR_VERSION, VIN_RELEASE)
51
52 extern struct vin_core *vin_core_gbl[VIN_MAX_DEV];
53
__vin_s_stream_handle(struct work_struct * work)54 void __vin_s_stream_handle(struct work_struct *work)
55 {
56 int ret = 0;
57 struct vin_vid_cap *cap =
58 container_of(work, struct vin_vid_cap, s_stream_task);
59
60 vin_timer_init(cap->vinc);
61 ret = vin_pipeline_call(cap->vinc, set_stream, &cap->pipe, cap->vinc->stream_idx);
62 if (ret < 0) {
63 vin_err("%s error!\n", __func__);
64 return;
65 }
66 /*set saved exp and gain for reopen*/
67 if (cap->vinc->exp_gain.exp_val && cap->vinc->exp_gain.gain_val) {
68 v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], core, ioctl,
69 VIDIOC_VIN_SENSOR_EXP_GAIN, &cap->vinc->exp_gain);
70 }
71
72 vin_log(VIN_LOG_VIDEO, "%s done, id = %d!\n", __func__, cap->vinc->id);
73 }
74
75 /*make sure addr was update to register*/
__check_bk_bufaddr(struct vin_core * vinc,struct vin_addr * paddr)76 static int __check_bk_bufaddr(struct vin_core *vinc, struct vin_addr *paddr)
77 {
78 unsigned int y, cb, cr;
79 /*unsigned int cnt = 0;*/
80
81 if (vinc->vid_cap.frame.fmt.fourcc == V4L2_PIX_FMT_YVU420) {
82 y = readl(vinc->base + 0x20) << 2;
83 cr = readl(vinc->base + 0x28) << 2;
84 cb = readl(vinc->base + 0x30) << 2;
85 } else {
86 y = readl(vinc->base + 0x20) << 2;
87 cb = readl(vinc->base + 0x28) << 2;
88 cr = readl(vinc->base + 0x30) << 2;
89 }
90
91 /*
92 while ((paddr->y != y || paddr->cb != cb || paddr->cr != cr) && (cnt < 2)) {
93 if(vinc->vid_cap.frame.fmt.fourcc == V4L2_PIX_FMT_YVU420) {
94 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_0_A, paddr->y);
95 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_2_A, paddr->cb);
96 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_1_A, paddr->cr);
97 y = readl(vinc->base + 0x20) << 2;
98 cr = readl(vinc->base + 0x28) << 2;
99 cb = readl(vinc->base + 0x30) << 2;
100
101 } else {
102 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_0_A, paddr->y);
103 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_1_A, paddr->cb);
104 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_2_A, paddr->cr);
105 y = readl(vinc->base + 0x20) << 2;
106 cb = readl(vinc->base + 0x28) << 2;
107 cr = readl(vinc->base + 0x30) << 2;
108 }
109 cnt++;
110 }
111 */
112
113 if (paddr->y != y || paddr->cb != cb || paddr->cr != cr) {
114 vin_err("vinc%d cannot write and read the right addr to register!!\n", vinc->id);
115 return -EINVAL;
116 }
117
118 return 0;
119 }
120
121 /* The color format (colplanes, memplanes) must be already configured. */
vin_set_addr(struct vin_core * vinc,struct vb2_buffer * vb,struct vin_frame * frame,struct vin_addr * paddr)122 int vin_set_addr(struct vin_core *vinc, struct vb2_buffer *vb,
123 struct vin_frame *frame, struct vin_addr *paddr)
124 {
125 u32 pix_size, depth, y_stride, u_stride, v_stride;
126 struct vb2_v4l2_buffer *vb2_v4l2;
127 struct vin_buffer *buf;
128
129 vb2_v4l2 = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
130 buf = container_of(vb2_v4l2, struct vin_buffer, vb);
131
132 if (vinc->vid_cap.special_active == 1) {
133 if (buf == NULL || buf->paddr == NULL)
134 return -EINVAL;
135 } else {
136 if (vb == NULL || frame == NULL)
137 return -EINVAL;
138 }
139
140 #if 1
141 pix_size = ALIGN(frame->o_width, VIN_ALIGN_WIDTH) * frame->o_height;
142 #else
143 pix_size = ALIGN(frame->o_width, VIN_ALIGN_WIDTH) * ALIGN(frame->o_height, VIN_ALIGN_HEIGHT);
144 #endif
145 depth = frame->fmt.depth[0] + frame->fmt.depth[1] + frame->fmt.depth[2];
146
147 if (vinc->vid_cap.special_active == 1) {
148 paddr->y = (dma_addr_t)buf->paddr;
149 frame->fmt.memplanes = 1;
150 } else
151 paddr->y = vb2_dma_contig_plane_dma_addr(vb, 0);
152
153 if (frame->fmt.memplanes == 1) {
154 switch (frame->fmt.colplanes) {
155 case 1:
156 paddr->cb = 0;
157 paddr->cr = 0;
158 break;
159 case 2:
160 /* decompose Y into Y/Cb */
161
162 if (frame->fmt.fourcc == V4L2_PIX_FMT_FBC) {
163 #if defined CONFIG_ARCH_SUN8IW12P1
164 paddr->cb = (u32)(paddr->y + CEIL_EXP(frame->o_width, 7) * CEIL_EXP(frame->o_height, 5) * 96);
165 #else
166 paddr->cb = paddr->y + ALIGN(DIV_ROUND_UP(frame->o_width, 128) * DIV_ROUND_UP(frame->o_height, 32) * 96, 64);
167 #endif
168 paddr->cr = 0;
169
170 } else {
171 paddr->cb = (u32)(paddr->y + pix_size);
172 paddr->cr = 0;
173 }
174 break;
175 case 3:
176 paddr->cb = (u32)(paddr->y + pix_size);
177 /* 420 */
178 if (frame->fmt.depth[0] == 12)
179 paddr->cr = (u32)(paddr->cb + (pix_size >> 2));
180 else /* 422 */
181 paddr->cr = (u32)(paddr->cb + (pix_size >> 1));
182 break;
183 default:
184 return -EINVAL;
185 }
186 } else if (!frame->fmt.mdataplanes) {
187 if (frame->fmt.memplanes >= 2)
188 paddr->cb = vb2_dma_contig_plane_dma_addr(vb, 1);
189
190 if (frame->fmt.memplanes == 3)
191 paddr->cr = vb2_dma_contig_plane_dma_addr(vb, 2);
192 }
193
194 #ifdef NO_SUPPROT_HARDWARE_CALCULATE
195 if ((vinc->vflip == 1) && (frame->fmt.fourcc == V4L2_PIX_FMT_FBC)) {
196 paddr->y += CEIL_EXP(frame->o_width, 7) * (CEIL_EXP(frame->o_height, 5) - 1) * 96;
197 paddr->cb += CEIL_EXP(frame->o_width, 4) * (CEIL_EXP(frame->o_height, 2) - 1) * 96;
198 paddr->cr = 0;
199 } else if (vinc->vflip == 1) {
200 switch (frame->fmt.colplanes) {
201 case 1:
202 paddr->y += (pix_size - frame->o_width) * frame->fmt.depth[0] / 8;
203 paddr->cb = 0;
204 paddr->cr = 0;
205 break;
206 case 2:
207 paddr->y += pix_size - frame->o_width;
208 /* 420 */
209 if (depth == 12)
210 paddr->cb += pix_size / 2 - frame->o_width;
211 else /* 422 */
212 paddr->cb += pix_size - frame->o_width;
213 paddr->cr = 0;
214 break;
215 case 3:
216 paddr->y += pix_size - frame->o_width;
217 if (depth == 12) {
218 paddr->cb += pix_size / 4 - frame->o_width / 2;
219 paddr->cr += pix_size / 4 - frame->o_width / 2;
220 } else {
221 paddr->cb += pix_size / 2 - frame->o_width / 2;
222 paddr->cr += pix_size / 2 - frame->o_width / 2;
223 }
224 break;
225 default:
226 return -EINVAL;
227 }
228 }
229 #endif
230 if ((vinc->large_image == 2) && (vinc->vin_status.frame_cnt % 2)) {
231 if (frame->fmt.colplanes == 3) {
232 if (depth == 12) {
233 /* 420 */
234 y_stride = frame->o_width / 2;
235 u_stride = frame->o_width / 2 / 2;
236 v_stride = frame->o_width / 2 / 2;
237 } else {
238 /* 422 */
239 y_stride = frame->o_width / 2;
240 u_stride = frame->o_width / 2;
241 v_stride = frame->o_width / 2;
242 }
243 } else {
244 y_stride = frame->o_width / 2;
245 u_stride = frame->o_width / 2;
246 v_stride = frame->o_width / 2;
247 }
248
249 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_0_A, paddr->y + y_stride);
250 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_1_A, paddr->cb + u_stride);
251 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_2_A, paddr->cr + v_stride);
252 } else {
253 if (vinc->vid_cap.frame.fmt.fourcc == V4L2_PIX_FMT_YVU420) {
254 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_0_A, paddr->y);
255 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_2_A, paddr->cb);
256 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_1_A, paddr->cr);
257 } else {
258 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_0_A, paddr->y);
259 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_1_A, paddr->cb);
260 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_2_A, paddr->cr);
261 }
262 if (__check_bk_bufaddr(vinc, paddr))
263 return -EINVAL;
264 }
265 return 0;
266 }
267
vin_set_next_buf_addr(struct vin_core * vinc)268 void vin_set_next_buf_addr(struct vin_core *vinc)
269 {
270 struct vin_vid_cap *cap = &vinc->vid_cap;
271 struct vin_buffer *buf;
272 __maybe_unused struct list_head *buf_next;
273 __maybe_unused int i;
274
275 if (vinc->large_image == 1)
276 return;
277
278 vinc->vid_cap.first_flag = 0;
279 vinc->vin_status.frame_cnt = 0;
280 vinc->vin_status.err_cnt = 0;
281 vinc->vin_status.lost_cnt = 0;
282
283 #ifndef BUF_AUTO_UPDATE
284 buf = list_entry(cap->vidq_active.next, struct vin_buffer, list);
285 vin_set_addr(vinc, &buf->vb.vb2_buf, &vinc->vid_cap.frame, &vinc->vid_cap.frame.paddr);
286 #else
287 vin_get_rest_buf_cnt(vinc);
288 cap->threshold.bufa_fifo_threshold = 1;
289 cap->threshold.stored_frm_threshold = 2;
290 cap->threshold.bufa_fifo_total = vinc->vin_status.buf_rest;
291 csic_buf_addr_fifo_en(vinc->vipp_sel, 1);
292 csic_set_threshold_for_bufa_mode(vinc->vipp_sel, &cap->threshold);
293 buf_next = cap->vidq_active.next;
294 for (i = 0; i < cap->threshold.bufa_fifo_total; i++) {
295 buf = list_entry(buf_next, struct vin_buffer, list);
296 vin_set_addr(vinc, &buf->vb.vb2_buf, &vinc->vid_cap.frame, &vinc->vid_cap.frame.paddr);
297 buf_next = buf_next->next;
298 }
299 #endif
300 }
301
lbc_mode_select(struct dma_lbc_cmp * lbc_cmp,unsigned int fourcc)302 static int lbc_mode_select(struct dma_lbc_cmp *lbc_cmp, unsigned int fourcc)
303 {
304 switch (fourcc) {
305 case V4L2_PIX_FMT_LBC_2_0X: /* 2x */
306 lbc_cmp->is_lossy = 1;
307 lbc_cmp->bit_depth = 8;
308 lbc_cmp->glb_enable = 1;
309 lbc_cmp->dts_enable = 1;
310 lbc_cmp->ots_enable = 1;
311 lbc_cmp->msq_enable = 1;
312 lbc_cmp->cmp_ratio_even = 600;
313 lbc_cmp->cmp_ratio_odd = 450;
314 lbc_cmp->mb_mi_bits[0] = 55;
315 lbc_cmp->mb_mi_bits[1] = 110;
316 lbc_cmp->rc_adv[0] = 60;
317 lbc_cmp->rc_adv[1] = 30;
318 lbc_cmp->rc_adv[2] = 15;
319 lbc_cmp->rc_adv[3] = 8;
320 lbc_cmp->lmtqp_en = 1;
321 lbc_cmp->lmtqp_min = 1;
322 lbc_cmp->updata_adv_en = 1;
323 lbc_cmp->updata_adv_ratio = 2;
324 break;
325 case V4L2_PIX_FMT_LBC_2_5X: /* 2.5x */
326 lbc_cmp->is_lossy = 1;
327 lbc_cmp->bit_depth = 8;
328 lbc_cmp->glb_enable = 1;
329 lbc_cmp->dts_enable = 1;
330 lbc_cmp->ots_enable = 1;
331 lbc_cmp->msq_enable = 1;
332 lbc_cmp->cmp_ratio_even = 440;
333 lbc_cmp->cmp_ratio_odd = 380;
334 lbc_cmp->mb_mi_bits[0] = 55;
335 lbc_cmp->mb_mi_bits[1] = 94;
336 lbc_cmp->rc_adv[0] = 60;
337 lbc_cmp->rc_adv[1] = 30;
338 lbc_cmp->rc_adv[2] = 15;
339 lbc_cmp->rc_adv[3] = 8;
340 lbc_cmp->lmtqp_en = 1;
341 lbc_cmp->lmtqp_min = 1;
342 lbc_cmp->updata_adv_en = 1;
343 lbc_cmp->updata_adv_ratio = 2;
344 break;
345 case V4L2_PIX_FMT_LBC_1_0X: /* lossless */
346 lbc_cmp->is_lossy = 0;
347 lbc_cmp->bit_depth = 8;
348 lbc_cmp->glb_enable = 1;
349 lbc_cmp->dts_enable = 1;
350 lbc_cmp->ots_enable = 1;
351 lbc_cmp->msq_enable = 1;
352 lbc_cmp->cmp_ratio_even = 1000;
353 lbc_cmp->cmp_ratio_odd = 1000;
354 lbc_cmp->mb_mi_bits[0] = 55;
355 lbc_cmp->mb_mi_bits[1] = 94;
356 lbc_cmp->rc_adv[0] = 60;
357 lbc_cmp->rc_adv[1] = 30;
358 lbc_cmp->rc_adv[2] = 15;
359 lbc_cmp->rc_adv[3] = 8;
360 lbc_cmp->lmtqp_en = 1;
361 lbc_cmp->lmtqp_min = 1;
362 lbc_cmp->updata_adv_en = 1;
363 lbc_cmp->updata_adv_ratio = 2;
364 break;
365 default:
366 return -1;
367 }
368 return 0;
369 }
370
371 /*
372 * Videobuf operations
373 */
queue_setup(struct vb2_queue * vq,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],struct device * alloc_devs[])374 static int queue_setup(struct vb2_queue *vq,
375 unsigned int *nbuffers, unsigned int *nplanes,
376 unsigned int sizes[], struct device *alloc_devs[])
377 {
378 struct vin_vid_cap *cap = vb2_get_drv_priv(vq);
379 unsigned int size;
380 int buf_max_flag = 0;
381 int wth;
382 int i;
383
384 cap->frame.bytesperline[0] = cap->frame.o_width * cap->frame.fmt.depth[0] / 8;
385 cap->frame.bytesperline[1] = cap->frame.o_width * cap->frame.fmt.depth[1] / 8;
386 cap->frame.bytesperline[2] = cap->frame.o_width * cap->frame.fmt.depth[2] / 8;
387
388 #if 0
389 size = cap->frame.o_width * cap->frame.o_height;
390 #else
391 size = roundup(cap->frame.o_width, VIN_ALIGN_WIDTH) * roundup(cap->frame.o_height, VIN_ALIGN_WIDTH);
392 #endif
393 switch (cap->frame.fmt.fourcc) {
394 case V4L2_PIX_FMT_FBC:
395 #if defined CONFIG_ARCH_SUN8IW12P1
396 cap->frame.payload[0] = (CEIL_EXP(cap->frame.o_width, 7) * CEIL_EXP(cap->frame.o_height, 5) +
397 CEIL_EXP(cap->frame.o_width, 4) * CEIL_EXP(cap->frame.o_height, 2)) * 96;
398 #else
399 cap->frame.payload[0] = (ALIGN(cap->frame.o_width / 16 * 96, 64) * (cap->frame.o_height / 4)) +
400 ALIGN(DIV_ROUND_UP(cap->frame.o_width, 128) * DIV_ROUND_UP(cap->frame.o_height, 32) * 96, 64);
401 #endif
402 break;
403 case V4L2_PIX_FMT_LBC_2_0X:
404 case V4L2_PIX_FMT_LBC_2_5X:
405 case V4L2_PIX_FMT_LBC_1_0X:
406 lbc_mode_select(&cap->lbc_cmp, cap->frame.fmt.fourcc);
407 wth = roundup(cap->frame.o_width, 32);
408 if (cap->lbc_cmp.is_lossy) {
409 cap->lbc_cmp.line_tar_bits[0] = roundup(cap->lbc_cmp.cmp_ratio_even * wth * cap->lbc_cmp.bit_depth/1000, 512);
410 cap->lbc_cmp.line_tar_bits[1] = roundup(cap->lbc_cmp.cmp_ratio_odd * wth * cap->lbc_cmp.bit_depth/500, 512);
411 } else {
412 cap->lbc_cmp.line_tar_bits[0] = roundup(wth * cap->lbc_cmp.bit_depth * 1 + (wth * 1 / 16 * 2), 512);
413 cap->lbc_cmp.line_tar_bits[1] = roundup(wth * cap->lbc_cmp.bit_depth * 2 + (wth * 2 / 16 * 2), 512);
414 }
415 cap->frame.payload[0] = (cap->lbc_cmp.line_tar_bits[0] + cap->lbc_cmp.line_tar_bits[1]) * cap->frame.o_height/2/8;
416 break;
417 default:
418 cap->frame.payload[0] = size * cap->frame.fmt.depth[0] / 8;
419 break;
420 }
421 cap->frame.payload[1] = size * cap->frame.fmt.depth[1] / 8;
422 cap->frame.payload[2] = size * cap->frame.fmt.depth[2] / 8;
423 cap->buf_byte_size =
424 PAGE_ALIGN(cap->frame.payload[0]) +
425 PAGE_ALIGN(cap->frame.payload[1]) +
426 PAGE_ALIGN(cap->frame.payload[2]);
427
428 size = cap->buf_byte_size;
429
430 if (size == 0)
431 return -EINVAL;
432
433 if (*nbuffers == 0)
434 *nbuffers = 8;
435
436 while (size * *nbuffers > MAX_FRAME_MEM) {
437 (*nbuffers)--;
438 buf_max_flag = 1;
439 if (*nbuffers == 0)
440 vin_err("Buffer size > max frame memory! count = %d\n",
441 *nbuffers);
442 }
443
444 if (buf_max_flag == 0) {
445 if (cap->capture_mode == V4L2_MODE_IMAGE) {
446 if (*nbuffers != 1) {
447 *nbuffers = 1;
448 vin_err("buffer count != 1 in capture mode\n");
449 }
450 } else {
451 if (*nbuffers < 3) {
452 #ifdef CONFIG_DISPPLAY_SYNC
453 if (cap->vinc->id != disp_sync_video)
454 *nbuffers = 3;
455 vin_warn("buffer count is %d\n", *nbuffers);
456 #else
457 *nbuffers = 3;
458 vin_err("buffer count is invalid, set to 3\n");
459 #endif
460 }
461 }
462 }
463
464 *nplanes = cap->frame.fmt.memplanes;
465 for (i = 0; i < *nplanes; i++) {
466 sizes[i] = cap->frame.payload[i];
467 alloc_devs[i] = cap->dev;
468 }
469 vin_log(VIN_LOG_VIDEO, "%s, buf count = %d, nplanes = %d, size = %d\n",
470 __func__, *nbuffers, *nplanes, size);
471 cap->vinc->vin_status.buf_cnt = *nbuffers;
472 cap->vinc->vin_status.buf_size = size;
473 return 0;
474 }
475
buffer_prepare(struct vb2_buffer * vb)476 static int buffer_prepare(struct vb2_buffer *vb)
477 {
478 struct vin_vid_cap *cap = vb2_get_drv_priv(vb->vb2_queue);
479 struct vb2_v4l2_buffer *vvb = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
480 struct vin_buffer *buf = container_of(vvb, struct vin_buffer, vb);
481 int i;
482
483 if (cap->frame.o_width < MIN_WIDTH || cap->frame.o_width > MAX_WIDTH ||
484 cap->frame.o_height < MIN_HEIGHT || cap->frame.o_height > MAX_HEIGHT) {
485 return -EINVAL;
486 }
487 /*size = dev->buf_byte_size;*/
488
489 for (i = 0; i < cap->frame.fmt.memplanes; i++) {
490 if (vb2_plane_size(vb, i) < cap->frame.payload[i]) {
491 vin_err("%s data will not fit into plane (%lu < %lu)\n",
492 __func__, vb2_plane_size(vb, i),
493 cap->frame.payload[i]);
494 return -EINVAL;
495 }
496 vb2_set_plane_payload(&buf->vb.vb2_buf, i, cap->frame.payload[i]);
497 vb->planes[i].m.offset = vb2_dma_contig_plane_dma_addr(vb, i);
498 }
499
500 return 0;
501 }
502
buffer_queue(struct vb2_buffer * vb)503 static void buffer_queue(struct vb2_buffer *vb)
504 {
505 struct vin_vid_cap *cap = vb2_get_drv_priv(vb->vb2_queue);
506 struct vb2_v4l2_buffer *vvb = container_of(vb, struct vb2_v4l2_buffer, vb2_buf);
507 struct vin_buffer *buf = container_of(vvb, struct vin_buffer, vb);
508 unsigned long flags = 0;
509
510 spin_lock_irqsave(&cap->slock, flags);
511 list_add_tail(&buf->list, &cap->vidq_active);
512 #ifdef BUF_AUTO_UPDATE
513 vin_set_addr(cap->vinc, &buf->vb.vb2_buf, &cap->frame, &cap->frame.paddr);
514 #endif
515 spin_unlock_irqrestore(&cap->slock, flags);
516 }
517
start_streaming(struct vb2_queue * vq,unsigned int count)518 static int start_streaming(struct vb2_queue *vq, unsigned int count)
519 {
520 return 0;
521 }
522
523 /* abort streaming and wait for last buffer */
stop_streaming(struct vb2_queue * vq)524 static void stop_streaming(struct vb2_queue *vq)
525 {
526 struct vin_vid_cap *cap = vb2_get_drv_priv(vq);
527 unsigned long flags = 0;
528
529 spin_lock_irqsave(&cap->slock, flags);
530 /* Release all active buffers */
531 while (!list_empty(&cap->vidq_active)) {
532 struct vin_buffer *buf;
533
534 buf = list_entry(cap->vidq_active.next, struct vin_buffer, list);
535 list_del(&buf->list);
536 vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
537 vin_log(VIN_LOG_VIDEO, "buf %d stop\n", buf->vb.vb2_buf.index);
538 }
539 spin_unlock_irqrestore(&cap->slock, flags);
540 }
541
542 static const struct vb2_ops vin_video_qops = {
543 .queue_setup = queue_setup,
544 .buf_prepare = buffer_prepare,
545 .buf_queue = buffer_queue,
546 .start_streaming = start_streaming,
547 .stop_streaming = stop_streaming,
548 .wait_prepare = vb2_ops_wait_prepare,
549 .wait_finish = vb2_ops_wait_finish,
550 };
551
552 /*
553 * IOCTL vidioc handling
554 */
vidioc_querycap(struct file * file,void * priv,struct v4l2_capability * cap)555 static int vidioc_querycap(struct file *file, void *priv,
556 struct v4l2_capability *cap)
557 {
558 strcpy(cap->driver, "sunxi-vin");
559 strcpy(cap->card, "sunxi-vin");
560
561 cap->version = VIN_VERSION;
562 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_STREAMING |
563 V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS;
564
565 cap->device_caps |= V4L2_CAP_EXT_PIX_FORMAT;
566
567 return 0;
568 }
569
vidioc_enum_fmt_vid_cap_mplane(struct file * file,void * priv,struct v4l2_fmtdesc * f)570 static int vidioc_enum_fmt_vid_cap_mplane(struct file *file, void *priv,
571 struct v4l2_fmtdesc *f)
572 {
573 struct vin_fmt *fmt;
574
575 fmt = vin_find_format(NULL, NULL, VIN_FMT_ALL, f->index, false);
576 if (!fmt)
577 return -EINVAL;
578
579 strlcpy(f->description, fmt->name, sizeof(f->description));
580 f->pixelformat = fmt->fourcc;
581 return 0;
582 }
583
vidioc_enum_framesizes(struct file * file,void * fh,struct v4l2_frmsizeenum * fsize)584 static int vidioc_enum_framesizes(struct file *file, void *fh,
585 struct v4l2_frmsizeenum *fsize)
586 {
587 struct vin_core *vinc = video_drvdata(file);
588 struct v4l2_subdev_frame_size_enum fse;
589 int ret;
590
591 if (vinc == NULL)
592 return -EINVAL;
593 fse.index = fsize->index;
594
595 ret = v4l2_subdev_call(vinc->vid_cap.pipe.sd[VIN_IND_SENSOR], pad,
596 enum_frame_size, NULL, &fse);
597 if (ret < 0)
598 return -1;
599 fsize->type = V4L2_FRMSIZE_TYPE_CONTINUOUS;
600 fsize->stepwise.max_width = fse.max_width;
601 fsize->stepwise.max_height = fse.max_height;
602 fsize->stepwise.min_width = fse.min_width;
603 fsize->stepwise.min_height = fse.min_height;
604 return 0;
605 }
606
vidioc_g_fmt_vid_cap_mplane(struct file * file,void * priv,struct v4l2_format * f)607 static int vidioc_g_fmt_vid_cap_mplane(struct file *file, void *priv,
608 struct v4l2_format *f)
609 {
610 struct vin_core *vinc = video_drvdata(file);
611 struct v4l2_pix_format_mplane *pixm = &f->fmt.pix_mp;
612 int i;
613
614 pixm->width = vinc->vid_cap.frame.o_width;
615 pixm->height = vinc->vid_cap.frame.o_height;
616 pixm->field = V4L2_FIELD_NONE;
617 pixm->pixelformat = vinc->vid_cap.frame.fmt.fourcc;
618 pixm->colorspace = vinc->vid_cap.frame.fmt.color;/*V4L2_COLORSPACE_JPEG;*/
619 pixm->num_planes = vinc->vid_cap.frame.fmt.memplanes;
620
621 for (i = 0; i < pixm->num_planes; ++i) {
622 pixm->plane_fmt[i].bytesperline = vinc->vid_cap.frame.bytesperline[i];
623 pixm->plane_fmt[i].sizeimage = vinc->vid_cap.frame.payload[i];
624 }
625 return 0;
626 }
627
vin_pipeline_try_format(struct vin_core * vinc,struct v4l2_mbus_framefmt * tfmt,struct vin_fmt ** fmt_id,bool set)628 static int vin_pipeline_try_format(struct vin_core *vinc,
629 struct v4l2_mbus_framefmt *tfmt,
630 struct vin_fmt **fmt_id,
631 bool set)
632 {
633 struct v4l2_subdev *sd = vinc->vid_cap.pipe.sd[VIN_IND_SENSOR];
634 struct v4l2_subdev_format sfmt;
635 struct media_entity *me;
636 struct vin_fmt *ffmt;
637 unsigned int mask;
638 struct media_graph graph;
639 int ret, i = 0, sd_ind;
640
641 if (WARN_ON(!sd || !tfmt || !fmt_id))
642 return -EINVAL;
643
644 memset(&sfmt, 0, sizeof(sfmt));
645 sfmt.format = *tfmt;
646 sfmt.which = set ? V4L2_SUBDEV_FORMAT_ACTIVE : V4L2_SUBDEV_FORMAT_TRY;
647
648 mask = (*fmt_id)->flags;
649 if ((mask & VIN_FMT_YUV) && (vinc->support_raw == 0))
650 mask = VIN_FMT_YUV;
651
652 /* when diffrent video output have same sensor,
653 * this pipeline try fmt will lead to false result.
654 * so it should be updated at later.
655 */
656 while (1) {
657
658 ffmt = vin_find_format(NULL, sfmt.format.code != 0 ? &sfmt.format.code : NULL,
659 mask, i++, true);
660 if (ffmt == NULL) {
661 /*
662 * Notify user-space if common pixel code for
663 * host and sensor does not exist.
664 */
665 vin_err("vin is not support this pixelformat\n");
666 return -EINVAL;
667 }
668
669 sfmt.format.code = tfmt->code = ffmt->mbus_code;
670 me = &vinc->vid_cap.subdev.entity;
671 if (media_graph_walk_init(&graph, me->graph_obj.mdev) != 0)
672 return -EINVAL;
673
674 media_graph_walk_start(&graph, me);
675 while ((me = media_graph_walk_next(&graph)) &&
676 me != &vinc->vid_cap.subdev.entity) {
677
678 sd = media_entity_to_v4l2_subdev(me);
679 switch (sd->grp_id) {
680 case VIN_GRP_ID_SENSOR:
681 sd_ind = VIN_IND_SENSOR;
682 break;
683 case VIN_GRP_ID_MIPI:
684 sd_ind = VIN_IND_MIPI;
685 break;
686 case VIN_GRP_ID_CSI:
687 sd_ind = VIN_IND_CSI;
688 break;
689 case VIN_GRP_ID_TDM_RX:
690 sd_ind = VIN_IND_TDM_RX;
691 break;
692 case VIN_GRP_ID_ISP:
693 sd_ind = VIN_IND_ISP;
694 break;
695 case VIN_GRP_ID_SCALER:
696 sd_ind = VIN_IND_SCALER;
697 break;
698 case VIN_GRP_ID_CAPTURE:
699 sd_ind = VIN_IND_CAPTURE;
700 break;
701 default:
702 sd_ind = VIN_IND_SENSOR;
703 break;
704 }
705
706 if (sd != vinc->vid_cap.pipe.sd[sd_ind])
707 continue;
708 vin_log(VIN_LOG_FMT, "found %s in this pipeline\n", me->name);
709
710 if (me->num_pads == 1 &&
711 (me->pads[0].flags & MEDIA_PAD_FL_SINK)) {
712 vin_log(VIN_LOG_FMT, "skip %s.\n", me->name);
713 continue;
714 }
715
716 sfmt.pad = 0;
717 ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &sfmt);
718 if (ret)
719 return ret;
720
721 /*set isp input win size for isp server call sensor_req_cfg*/
722 if (sd->grp_id == VIN_GRP_ID_ISP)
723 sensor_isp_input(vinc->vid_cap.pipe.sd[VIN_IND_SENSOR], &sfmt.format);
724
725 /*change output resolution of scaler*/
726 if (sd->grp_id == VIN_GRP_ID_SCALER) {
727 sfmt.format.width = tfmt->width;
728 sfmt.format.height = tfmt->height;
729 }
730
731 if (me->pads[0].flags & MEDIA_PAD_FL_SINK) {
732 sfmt.pad = me->num_pads - 1;
733 ret = v4l2_subdev_call(sd, pad, set_fmt, NULL, &sfmt);
734 if (ret)
735 return ret;
736 }
737 }
738
739 if (sfmt.format.code != tfmt->code)
740 continue;
741
742 if (ffmt->mbus_code)
743 sfmt.format.code = ffmt->mbus_code;
744
745 break;
746 }
747
748 if (ffmt)
749 *fmt_id = ffmt;
750 *tfmt = sfmt.format;
751
752 return 0;
753 }
754
vin_pipeline_set_mbus_config(struct vin_core * vinc)755 static int vin_pipeline_set_mbus_config(struct vin_core *vinc)
756 {
757 struct vin_pipeline *pipe = &vinc->vid_cap.pipe;
758 struct v4l2_subdev *sd = pipe->sd[VIN_IND_SENSOR];
759 struct v4l2_mbus_config mcfg;
760 struct media_entity *me;
761 struct media_graph graph;
762 struct csi_dev *csi = NULL;
763 int ret;
764
765 ret = v4l2_subdev_call(sd, pad, get_mbus_config, 0, &mcfg);
766 if (ret < 0) {
767 vin_err("%s get_mbus_config error!\n", sd->name);
768 goto out;
769 }
770 /* s_mbus_config on all mipi and csi */
771 me = &vinc->vid_cap.subdev.entity;
772 if (media_graph_walk_init(&graph, me->graph_obj.mdev) != 0)
773 return -EINVAL;
774 media_graph_walk_start(&graph, me);
775 while ((me = media_graph_walk_next(&graph)) &&
776 me != &vinc->vid_cap.subdev.entity) {
777 sd = media_entity_to_v4l2_subdev(me);
778 if ((sd == pipe->sd[VIN_IND_MIPI]) ||
779 (sd == pipe->sd[VIN_IND_CSI])) {
780 ret = sd->ops->pad->set_mbus_config(sd, 0, &mcfg);
781 //ret = v4l2_subdev_call(sd, pad, set_mbus_config,0, &mcfg);
782 if (ret < 0) {
783 vin_err("%s set_mbus_config error!\n", me->name);
784 goto out;
785 }
786 }
787 }
788
789 csi = v4l2_get_subdevdata(pipe->sd[VIN_IND_CSI]);
790 vinc->total_rx_ch = csi->bus_info.ch_total_num;
791 vinc->vid_cap.frame.fmt.mbus_type = mcfg.type;
792 #ifdef SUPPORT_PTN
793 if (vinc->ptn_cfg.ptn_en) {
794 csi->bus_info.bus_if = V4L2_MBUS_PARALLEL;
795 switch (vinc->ptn_cfg.ptn_dw) {
796 case 0:
797 csi->csi_fmt->data_width = 8;
798 break;
799 case 1:
800 csi->csi_fmt->data_width = 10;
801 break;
802 case 2:
803 csi->csi_fmt->data_width = 12;
804 break;
805 default:
806 csi->csi_fmt->data_width = 12;
807 break;
808 }
809 }
810 #endif
811 return 0;
812 out:
813 return ret;
814
815 }
816
vidioc_try_fmt_vid_cap_mplane(struct file * file,void * priv,struct v4l2_format * f)817 static int vidioc_try_fmt_vid_cap_mplane(struct file *file, void *priv,
818 struct v4l2_format *f)
819 {
820 struct vin_core *vinc = video_drvdata(file);
821 struct v4l2_mbus_framefmt mf;
822 struct vin_fmt *ffmt = NULL;
823
824 ffmt = vin_find_format(&f->fmt.pix_mp.pixelformat, NULL,
825 VIN_FMT_ALL, -1, false);
826 if (ffmt == NULL) {
827 vin_err("vin is not support this pixelformat\n");
828 return -EINVAL;
829 }
830
831 mf.width = f->fmt.pix_mp.width;
832 mf.height = f->fmt.pix_mp.height;
833 mf.code = ffmt->mbus_code;
834 vin_pipeline_try_format(vinc, &mf, &ffmt, true);
835
836 f->fmt.pix_mp.width = mf.width;
837 f->fmt.pix_mp.height = mf.height;
838 f->fmt.pix_mp.colorspace = mf.colorspace;
839 return 0;
840 }
841
842
__vin_set_fmt(struct vin_core * vinc,struct v4l2_format * f)843 static int __vin_set_fmt(struct vin_core *vinc, struct v4l2_format *f)
844 {
845 struct vin_vid_cap *cap = &vinc->vid_cap;
846 struct sensor_win_size win_cfg;
847 struct v4l2_mbus_framefmt mf;
848 struct vin_fmt *ffmt = NULL;
849 struct mbus_framefmt_res *res = (void *)mf.reserved;
850 int ret = 0;
851
852 if (vin_streaming(cap)) {
853 vin_err("%s device busy\n", __func__);
854 return -EBUSY;
855 }
856
857 ffmt = vin_find_format(&f->fmt.pix_mp.pixelformat, NULL,
858 VIN_FMT_ALL, -1, false);
859 if (ffmt == NULL) {
860 vin_err("vin does not support this pixelformat 0x%x\n",
861 f->fmt.pix_mp.pixelformat);
862 return -EINVAL;
863 }
864
865 cap->frame.fmt = *ffmt;
866 mf.width = f->fmt.pix_mp.width;
867 mf.height = f->fmt.pix_mp.height;
868 mf.field = f->fmt.pix_mp.field;
869 mf.colorspace = f->fmt.pix_mp.colorspace;
870 mf.code = ffmt->mbus_code;
871 res->res_pix_fmt = f->fmt.pix_mp.pixelformat;
872 ret = vin_pipeline_try_format(vinc, &mf, &ffmt, true);
873 if (ret < 0) {
874 vin_err("vin_pipeline_try_format failed\n");
875 return -EINVAL;
876 }
877 cap->frame.fmt.mbus_code = mf.code;
878 cap->frame.fmt.field = mf.field;
879 cap->frame.fmt.color = mf.colorspace;
880
881 f->fmt.pix_mp.colorspace = mf.colorspace;
882
883 vin_log(VIN_LOG_FMT, "pipeline try fmt %d*%d code %x field %d colorspace %d\n",
884 mf.width, mf.height, mf.code, mf.field, mf.colorspace);
885
886 vin_pipeline_set_mbus_config(vinc);
887
888 /*get current win configs*/
889 memset(&win_cfg, 0, sizeof(struct sensor_win_size));
890 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], core, ioctl,
891 GET_CURRENT_WIN_CFG, &win_cfg);
892 if (ret == 0) {
893 struct v4l2_subdev_pad_config cfg;
894 struct v4l2_subdev_selection sel;
895
896 sunxi_isp_sensor_fps(cap->pipe.sd[VIN_IND_ISP], win_cfg.fps_fixed);
897
898 vinc->vin_status.width = win_cfg.width;
899 vinc->vin_status.height = win_cfg.height;
900 vinc->vin_status.h_off = win_cfg.hoffset;
901 vinc->vin_status.v_off = win_cfg.voffset;
902 /*parser crop*/
903 cfg.try_crop.width = win_cfg.width;
904 cfg.try_crop.height = win_cfg.height;
905 cfg.try_crop.left = win_cfg.hoffset;
906 cfg.try_crop.top = win_cfg.voffset;
907
908 sel.which = V4L2_SUBDEV_FORMAT_TRY;
909 sel.pad = cap->pipe.sd[VIN_IND_CSI]->entity.num_pads - 1;
910
911 if (cap->pipe.sd[VIN_IND_CSI]) {
912 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_CSI], pad,
913 set_selection, &cfg, &sel);
914 if (ret < 0) {
915 vin_err("csi parser set_selection error! code = %d, %d\n", ret, -ENODEV);
916 goto out;
917 }
918
919 } else {
920 vin_err("csi sd is null\n");
921
922 }
923
924 /*vipp crop*/
925 if ((win_cfg.vipp_hoff != 0) || (win_cfg.vipp_voff != 0)) {
926 if ((win_cfg.vipp_w + win_cfg.vipp_hoff > win_cfg.width_input) || (win_cfg.vipp_w == 0))
927 win_cfg.vipp_w = win_cfg.width_input - win_cfg.vipp_hoff;
928 if ((win_cfg.vipp_h + win_cfg.vipp_voff > win_cfg.height_input) || (win_cfg.vipp_h == 0))
929 win_cfg.vipp_h = win_cfg.height_input - win_cfg.vipp_voff;
930 sel.target = V4L2_SEL_TGT_CROP;
931 sel.pad = SCALER_PAD_SINK;
932 sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
933 sel.r.width = win_cfg.vipp_w;
934 sel.r.height = win_cfg.vipp_h;
935 sel.r.left = win_cfg.vipp_hoff;
936 sel.r.top = win_cfg.vipp_voff;
937 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_SCALER],
938 pad, set_selection, NULL, &sel);
939 if (ret < 0) {
940 vin_err("vipp set_selection crop error!\n");
941 goto out;
942 }
943 }
944
945 /*vipp shrink*/
946 if ((win_cfg.vipp_wshrink != 0) && (win_cfg.vipp_hshrink != 0)) {
947 sel.target = V4L2_SEL_TGT_CROP;
948 sel.pad = SCALER_PAD_SINK;
949 sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
950 sel.reserved[0] = VIPP_ONLY_SHRINK;
951 sel.r.width = win_cfg.vipp_wshrink;
952 sel.r.height = win_cfg.vipp_hshrink;
953 sel.r.left = 0;
954 sel.r.top = 0;
955 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_SCALER],
956 pad, set_selection, NULL, &sel);
957 if (ret < 0) {
958 vin_err("vipp set_selection shrink error!\n");
959 goto out;
960 }
961 }
962 } else {
963 ret = 0;
964 vinc->vin_status.width = mf.width;
965 vinc->vin_status.height = mf.height;
966 vinc->vin_status.h_off = 0;
967 vinc->vin_status.v_off = 0;
968 vin_warn("get sensor win_cfg failed!\n");
969 }
970
971 if (vinc->vid_cap.frame.fmt.mbus_type == V4L2_MBUS_SUBLVDS ||
972 vinc->vid_cap.frame.fmt.mbus_type == V4L2_MBUS_HISPI) {
973 struct combo_sync_code sync;
974 struct combo_lane_map map;
975 struct combo_wdr_cfg wdr;
976
977 memset(&sync, 0, sizeof(sync));
978 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], core,
979 ioctl, GET_COMBO_SYNC_CODE, &sync);
980 if (ret < 0) {
981 vin_err("get combo sync code error!\n");
982 goto out;
983 }
984 sunxi_combo_set_sync_code(cap->pipe.sd[VIN_IND_MIPI], &sync);
985
986 memset(&map, 0, sizeof(map));
987 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], core,
988 ioctl, GET_COMBO_LANE_MAP, &map);
989 if (ret < 0) {
990 vin_err("get combo lane map error!\n");
991 goto out;
992 }
993 sunxi_combo_set_lane_map(cap->pipe.sd[VIN_IND_MIPI], &map);
994
995 if (res->res_combo_mode & 0xf) {
996 memset(&wdr, 0, sizeof(wdr));
997 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], core,
998 ioctl, GET_COMBO_WDR_CFG, &wdr);
999 if (ret < 0) {
1000 vin_err("get combo wdr cfg error!\n");
1001 goto out;
1002 }
1003 sunxi_combo_wdr_config(cap->pipe.sd[VIN_IND_MIPI], &wdr);
1004 }
1005 }
1006 cap->isp_wdr_mode = res->res_wdr_mode;
1007
1008 if (cap->capture_mode == V4L2_MODE_IMAGE) {
1009 sunxi_flash_check_to_start(cap->pipe.sd[VIN_IND_FLASH],
1010 SW_CTRL_FLASH_ON);
1011 } else {
1012 sunxi_flash_stop(vinc->vid_cap.pipe.sd[VIN_IND_FLASH]);
1013 }
1014
1015 if ((mf.width < f->fmt.pix_mp.width) || (mf.height < f->fmt.pix_mp.height)) {
1016 f->fmt.pix_mp.width = mf.width;
1017 f->fmt.pix_mp.height = mf.height;
1018 }
1019 /*for csi dma size set*/
1020 cap->frame.offs_h = (mf.width - f->fmt.pix_mp.width) / 2;
1021 cap->frame.offs_v = (mf.height - f->fmt.pix_mp.height) / 2;
1022 cap->frame.o_width = f->fmt.pix_mp.width;
1023 cap->frame.o_height = f->fmt.pix_mp.height;
1024
1025 out:
1026 return ret;
1027 }
1028
1029
vidioc_s_fmt_vid_cap_mplane(struct file * file,void * priv,struct v4l2_format * f)1030 static int vidioc_s_fmt_vid_cap_mplane(struct file *file, void *priv,
1031 struct v4l2_format *f)
1032 {
1033 struct vin_core *vinc = video_drvdata(file);
1034
1035 return __vin_set_fmt(vinc, f);
1036 }
1037
vidioc_s_selection(struct file * file,void * fh,struct v4l2_selection * s)1038 int vidioc_s_selection(struct file *file, void *fh,
1039 struct v4l2_selection *s)
1040 {
1041 struct vin_core *vinc = video_drvdata(file);
1042 struct v4l2_subdev_selection sel;
1043 int ret = 0;
1044
1045 sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1046 sel.pad = SCALER_PAD_SINK;
1047 sel.target = s->target;
1048 sel.flags = s->flags;
1049 sel.r = s->r;
1050 ret = v4l2_subdev_call(vinc->vid_cap.pipe.sd[VIN_IND_SCALER], pad,
1051 set_selection, NULL, &sel);
1052 if (ret < 0)
1053 vin_err("v4l2 sub device scaler set_selection error!\n");
1054 return ret;
1055 }
vidioc_g_selection(struct file * file,void * fh,struct v4l2_selection * s)1056 int vidioc_g_selection(struct file *file, void *fh,
1057 struct v4l2_selection *s)
1058 {
1059 struct vin_core *vinc = video_drvdata(file);
1060 struct v4l2_subdev_selection sel;
1061 int ret = 0;
1062
1063 sel.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1064 sel.pad = SCALER_PAD_SINK;
1065 sel.target = s->target;
1066 sel.flags = s->flags;
1067 ret = v4l2_subdev_call(vinc->vid_cap.pipe.sd[VIN_IND_SCALER], pad,
1068 get_selection, NULL, &sel);
1069 if (ret < 0)
1070 vin_err("v4l2 sub device scaler get_selection error!\n");
1071 else
1072 s->r = sel.r;
1073 return ret;
1074
1075 }
1076
vidioc_enum_fmt_vid_overlay(struct file * file,void * __fh,struct v4l2_fmtdesc * f)1077 static int vidioc_enum_fmt_vid_overlay(struct file *file, void *__fh,
1078 struct v4l2_fmtdesc *f)
1079 {
1080 struct vin_fmt *fmt;
1081
1082 fmt = vin_find_format(NULL, NULL, VIN_FMT_OSD, f->index, false);
1083 if (!fmt)
1084 return -EINVAL;
1085
1086 strlcpy(f->description, fmt->name, sizeof(f->description));
1087 f->pixelformat = fmt->fourcc;
1088 return 0;
1089 }
1090
vidioc_g_fmt_vid_overlay(struct file * file,void * __fh,struct v4l2_format * f)1091 static int vidioc_g_fmt_vid_overlay(struct file *file, void *__fh,
1092 struct v4l2_format *f)
1093 {
1094 struct vin_core *vinc = video_drvdata(file);
1095
1096 f->fmt.win.w.left = 0;
1097 f->fmt.win.w.top = 0;
1098 f->fmt.win.w.width = vinc->vid_cap.frame.o_width;
1099 f->fmt.win.w.height = vinc->vid_cap.frame.o_height;
1100 f->fmt.win.clipcount = vinc->vid_cap.osd.overlay_cnt;
1101 f->fmt.win.chromakey = vinc->vid_cap.osd.chromakey;
1102
1103 return 0;
1104 }
__osd_win_check(struct v4l2_window * win)1105 static void __osd_win_check(struct v4l2_window *win)
1106 {
1107 if (win->w.width > MAX_WIDTH)
1108 win->w.width = MAX_WIDTH;
1109 if (win->w.width < MIN_WIDTH)
1110 win->w.width = MIN_WIDTH;
1111 if (win->w.height > MAX_HEIGHT)
1112 win->w.height = MAX_HEIGHT;
1113 if (win->w.height < MIN_HEIGHT)
1114 win->w.height = MIN_HEIGHT;
1115
1116 if (win->bitmap) {
1117 if (win->clipcount > MAX_OVERLAY_NUM)
1118 win->clipcount = MAX_OVERLAY_NUM;
1119 } else {
1120 if (MAX_ORL_NUM) {
1121 if (win->clipcount > MAX_ORL_NUM)
1122 win->clipcount = MAX_ORL_NUM;
1123 } else {
1124 if (win->clipcount > MAX_COVER_NUM)
1125 win->clipcount = MAX_COVER_NUM;
1126 }
1127 }
1128 }
1129
vidioc_try_fmt_vid_overlay(struct file * file,void * __fh,struct v4l2_format * f)1130 static int vidioc_try_fmt_vid_overlay(struct file *file, void *__fh,
1131 struct v4l2_format *f)
1132 {
1133 __osd_win_check(&f->fmt.win);
1134
1135 return 0;
1136 }
1137
__osd_bitmap2dram(struct vin_osd * osd,void * databuf)1138 void __osd_bitmap2dram(struct vin_osd *osd, void *databuf)
1139 {
1140 #if defined CONFIG_ARCH_SUN8IW12P1
1141 int i, j, k, m = 0, n = 0;
1142 int kend = 0, idx = 0, ww = 0, ysn = 0;
1143 int y_num = 0, *y_temp = NULL;
1144 int *hor_num = NULL, *hor_index = NULL;
1145 int *x_temp = NULL, *xbuf = NULL, *x_idx = NULL;
1146 int addr_offset = 0, pix_size = osd->fmt->depth[0]/8;
1147 int cnt = osd->overlay_cnt;
1148 void *dram_addr = osd->ov_mask[osd->ov_set_cnt % 2].vir_addr;
1149
1150 y_temp = (int *)kzalloc(2 * cnt * sizeof(int), GFP_KERNEL);
1151 for (i = 0; i < cnt; i++) {
1152 y_temp[i] = osd->ov_win[i].top;
1153 y_temp[i + cnt] = osd->ov_win[i].top + osd->ov_win[i].height - 1;
1154 }
1155 sort(y_temp, 2 * cnt, sizeof(int), vin_cmp, vin_swap);
1156 y_num = vin_unique(y_temp, 2 * cnt);
1157 hor_num = (int *)kzalloc(y_num * sizeof(int), GFP_KERNEL); /*0~y_num-1*/
1158 hor_index = (int *)kzalloc(y_num * cnt * sizeof(int), GFP_KERNEL); /*(0~y_num-1) * (0~N+1)*/
1159
1160 for (j = 0; j < y_num; j++) {
1161 ysn = 0;
1162 for (i = 0; i < cnt; i++) {
1163 if (osd->ov_win[i].top <= y_temp[j] &&
1164 (osd->ov_win[i].top + osd->ov_win[i].height) > y_temp[j]) {
1165 hor_num[j]++;
1166 hor_index[j * cnt + ysn] = i;
1167 ysn = ysn + 1;
1168 }
1169 }
1170 }
1171
1172 for (j = 0; j < y_num; j++) {
1173 x_temp = (int *)kzalloc(hor_num[j] * sizeof(int), GFP_KERNEL);
1174 xbuf = (int *)kzalloc(hor_num[j] * sizeof(int), GFP_KERNEL);
1175 x_idx = (int *)kzalloc(hor_num[j] * sizeof(int), GFP_KERNEL);
1176 for (k = 0; k < hor_num[j]; k++)
1177 x_temp[k] = osd->ov_win[hor_index[j * cnt + k]].left;
1178 memcpy(xbuf, x_temp, hor_num[j] * sizeof(int));
1179 sort(x_temp, hor_num[j], sizeof(int), vin_cmp, vin_swap);
1180
1181 for (k = 0; k < hor_num[j]; k++) {
1182 for (m = 0; m < hor_num[j]; m++) {
1183 if (x_temp[k] == xbuf[m]) {
1184 x_idx[k] = m;
1185 break;
1186 }
1187 }
1188 }
1189
1190 if (j == y_num - 1)
1191 kend = y_temp[j];
1192 else
1193 kend = y_temp[j + 1] - 1;
1194 for (k = y_temp[j]; k <= kend; k++) {
1195 for (i = 0; i < hor_num[j]; i++) {
1196 idx = hor_index[j * cnt + x_idx[i]];
1197 addr_offset = 0;
1198 for (n = 0; n < idx; n++)
1199 addr_offset += (osd->ov_win[n].width * osd->ov_win[n].height) * pix_size;
1200 ww = osd->ov_win[idx].width;
1201 if (k < (osd->ov_win[idx].top + osd->ov_win[idx].height)) {
1202 memcpy(dram_addr, databuf + addr_offset
1203 + ww * (k - osd->ov_win[idx].top) * pix_size,
1204 ww * pix_size);
1205 dram_addr += ww * pix_size;
1206 }
1207 }
1208 }
1209 kfree(x_temp);
1210 kfree(xbuf);
1211 kfree(x_idx);
1212 x_temp = NULL;
1213 xbuf = NULL;
1214 x_idx = NULL;
1215 }
1216 kfree(hor_num);
1217 kfree(hor_index);
1218 kfree(y_temp);
1219 y_temp = NULL;
1220 hor_index = NULL;
1221 hor_num = NULL;
1222 #else
1223 memcpy(osd->ov_mask[osd->ov_set_cnt % 2].vir_addr, databuf, osd->ov_mask[osd->ov_set_cnt % 2].size);
1224 #endif
1225 }
1226
__osd_rgb_to_yuv(u8 r,u8 g,u8 b,u8 * y,u8 * u,u8 * v)1227 static void __osd_rgb_to_yuv(u8 r, u8 g, u8 b, u8 *y, u8 *u, u8 *v)
1228 {
1229 int jc0 = 0x00000132;
1230 int jc1 = 0x00000259;
1231 int jc2 = 0x00000075;
1232 int jc3 = 0xffffff53;
1233 int jc4 = 0xfffffead;
1234 int jc5 = 0x00000200;
1235 int jc6 = 0x00000200;
1236 int jc7 = 0xfffffe53;
1237 int jc8 = 0xffffffad;
1238 int jc9 = 0x00000000;
1239 int jc10 = 0x00000080;
1240 int jc11 = 0x00000080;
1241 u32 y_tmp, u_tmp, v_tmp;
1242
1243 y_tmp = (((jc0 * r >> 6) + (jc1 * g >> 6) + (jc2 * b >> 6)) >> 4) + jc9;
1244 *y = clamp_val(y_tmp, 0, 255);
1245
1246 u_tmp = (((jc3 * r >> 6) + (jc4 * g >> 6) + (jc5 * b >> 6)) >> 4) + jc10;
1247 *u = clamp_val(u_tmp, 0, 255);
1248
1249 v_tmp = (((jc6 * r >> 6) + (jc7 * g >> 6) + (jc8 * b >> 6)) >> 4) + jc11;
1250 *v = clamp_val(v_tmp, 0, 255);
1251 }
1252
__osd_bmp_to_yuv(struct vin_osd * osd,void * databuf)1253 static void __osd_bmp_to_yuv(struct vin_osd *osd, void *databuf)
1254 {
1255 #if defined CONFIG_ARCH_SUN8IW12P1
1256 u8 alpha, r, g, b, y, u, v;
1257 int i, j, y_sum, bmp;
1258
1259 for (i = 0; i < osd->overlay_cnt; i++) {
1260 int bmp_size = osd->ov_win[i].height * osd->ov_win[i].width;
1261 int valid_pix = 1;
1262
1263 y_sum = 0;
1264 for (j = 0; j < bmp_size; j++) {
1265 switch (osd->overlay_fmt) {
1266 case 0:
1267 bmp = *(short *)databuf;
1268 alpha = (int)((bmp >> 15) & 0x01) * 100;
1269 r = (bmp >> 10) & 0x1f;
1270 r = (r << 3) + (r >> 2);
1271 g = (bmp >> 5) & 0x1f;
1272 g = (g << 3) + (g >> 2);
1273 b = bmp & 0x1f;
1274 b = (b << 3) + (b >> 2);
1275 databuf += 2;
1276 break;
1277 case 1:
1278 bmp = *(short *)databuf;
1279 alpha = (int)((bmp >> 12) & 0x0f) * 100 / 15;
1280 r = (bmp >> 8) & 0x0f;
1281 r = (r << 4) + r;
1282 g = (bmp >> 4) & 0x0f;
1283 g = (g << 4) + g;
1284 b = bmp & 0x0f;
1285 b = (b << 4) + b;
1286 databuf += 2;
1287 break;
1288 case 2:
1289 bmp = *(int *)databuf;
1290 alpha = (int)((bmp >> 24) & 0xff) * 100 / 255;
1291 r = (bmp >> 16) & 0xff;
1292 g = (bmp >> 8) & 0xff;
1293 b = bmp & 0xff;
1294 databuf += 4;
1295 break;
1296 default:
1297 bmp = *(int *)databuf;
1298 alpha = (int)((bmp >> 24) & 0xff) * 100 / 255;
1299 r = (bmp >> 16) & 0xff;
1300 g = (bmp >> 8) & 0xff;
1301 b = bmp & 0xff;
1302 databuf += 4;
1303 break;
1304 }
1305 if (alpha >= 80) {
1306 __osd_rgb_to_yuv(r, g, b, &y, &u, &v);
1307 y_sum += y;
1308 valid_pix++;
1309 }
1310 }
1311 osd->y_bmp_avp[i] = y_sum / valid_pix;
1312 }
1313 #endif
1314 }
1315
vidioc_s_fmt_vid_overlay(struct file * file,void * __fh,struct v4l2_format * f)1316 static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh,
1317 struct v4l2_format *f)
1318 {
1319 struct vin_core *vinc = video_drvdata(file);
1320 struct vin_osd *osd = &vinc->vid_cap.osd;
1321 struct v4l2_clip *clip = NULL;
1322 void *bitmap = NULL;
1323 unsigned int bitmap_size = 0, pix_size = 0;
1324 int ret = 0, i = 0;
1325
1326 __osd_win_check(&f->fmt.win);
1327
1328 osd->chromakey = f->fmt.win.chromakey;
1329
1330 if (f->fmt.win.bitmap) {
1331 if (f->fmt.win.clipcount <= 0) {
1332 osd->overlay_en = 0;
1333 goto osd_reset;
1334 } else {
1335 if (MAX_OVERLAY_NUM) {
1336 osd->overlay_en = 1;
1337 osd->overlay_cnt = f->fmt.win.clipcount;
1338 } else {
1339 osd->overlay_en = 0;
1340 vin_err("VIPP overlay is not exist!!\n");
1341 goto osd_reset;
1342 }
1343 }
1344
1345 clip = vmalloc(sizeof(struct v4l2_clip) * osd->overlay_cnt * 2);
1346 if (clip == NULL) {
1347 vin_err("%s - Alloc of clip mask failed\n", __func__);
1348 return -ENOMEM;
1349 }
1350 if (copy_from_user(clip, f->fmt.win.clips,
1351 sizeof(struct v4l2_clip) * osd->overlay_cnt * 2)) {
1352 vfree(clip);
1353 return -EFAULT;
1354 }
1355
1356 /*save global alpha in the win top for diff overlay*/
1357 for (i = 0; i < osd->overlay_cnt; i++) {
1358 osd->ov_win[i] = clip[i].c;
1359 bitmap_size += clip[i].c.width * clip[i].c.height;
1360 if (f->fmt.win.global_alpha == 255)
1361 osd->global_alpha[i] = clamp_val(clip[i + osd->overlay_cnt].c.top, 0, 16);
1362 else
1363 osd->global_alpha[i] = clamp_val(f->fmt.win.global_alpha, 0, 16);
1364 osd->inverse_close[i] = clip[i + osd->overlay_cnt].c.left & 0xff;
1365 osd->inv_th = (clip[i + osd->overlay_cnt].c.left >> 8) & 0xff;
1366 osd->inv_w_rgn[i] = clamp_val(clip[i + osd->overlay_cnt].c.width, 0, 15);
1367 osd->inv_h_rgn[i] = clamp_val(clip[i + osd->overlay_cnt].c.height, 0, 15);
1368 }
1369 vfree(clip);
1370
1371 osd->fmt = vin_find_format(&f->fmt.win.chromakey, NULL,
1372 VIN_FMT_OSD, -1, false);
1373 if (osd->fmt == NULL) {
1374 vin_err("osd is not support this chromakey\n");
1375 return -EINVAL;
1376 }
1377 pix_size = osd->fmt->depth[0]/8;
1378
1379 bitmap = vmalloc(bitmap_size * pix_size);
1380 if (bitmap == NULL) {
1381 vin_err("%s - Alloc of bitmap buf failed\n", __func__);
1382 return -ENOMEM;
1383 }
1384 if (copy_from_user(bitmap, f->fmt.win.bitmap,
1385 bitmap_size * pix_size)) {
1386 vfree(bitmap);
1387 return -EFAULT;
1388 }
1389
1390 osd->ov_set_cnt++;
1391
1392 if (osd->ov_mask[osd->ov_set_cnt % 2].size != bitmap_size * pix_size) {
1393 if (osd->ov_mask[osd->ov_set_cnt % 2].phy_addr) {
1394 os_mem_free(&vinc->pdev->dev, &osd->ov_mask[osd->ov_set_cnt % 2]);
1395 osd->ov_mask[osd->ov_set_cnt % 2].phy_addr = NULL;
1396 }
1397 osd->ov_mask[osd->ov_set_cnt % 2].size = bitmap_size * pix_size;
1398 ret = os_mem_alloc(&vinc->pdev->dev, &osd->ov_mask[osd->ov_set_cnt % 2]);
1399 if (ret < 0) {
1400 vin_err("osd bitmap load addr requset failed!\n");
1401 vfree(bitmap);
1402 return -ENOMEM;
1403 }
1404 }
1405 memset(osd->ov_mask[osd->ov_set_cnt % 2].vir_addr, 0, bitmap_size * pix_size);
1406 __osd_bitmap2dram(osd, bitmap);
1407
1408 switch (osd->chromakey) {
1409 case V4L2_PIX_FMT_RGB555:
1410 osd->overlay_fmt = ARGB1555;
1411 break;
1412 case V4L2_PIX_FMT_RGB444:
1413 osd->overlay_fmt = ARGB4444;
1414 break;
1415 case V4L2_PIX_FMT_RGB32:
1416 osd->overlay_fmt = ARGB8888;
1417 break;
1418 default:
1419 osd->overlay_fmt = ARGB8888;
1420 break;
1421 }
1422 __osd_bmp_to_yuv(osd, bitmap);
1423 vfree(bitmap);
1424 } else {
1425 if (f->fmt.win.clipcount <= 0) {
1426 osd->cover_en = 0;
1427 osd->orl_en = 0;
1428 goto osd_reset;
1429 }
1430
1431 clip = vmalloc(sizeof(struct v4l2_clip) * f->fmt.win.clipcount * 2);
1432 if (clip == NULL) {
1433 vin_err("%s - Alloc of clip mask failed\n", __func__);
1434 return -ENOMEM;
1435 }
1436 if (copy_from_user(clip, f->fmt.win.clips,
1437 sizeof(struct v4l2_clip) * f->fmt.win.clipcount * 2)) {
1438 vfree(clip);
1439 return -EFAULT;
1440 }
1441
1442 /*save rgb in the win top for diff cover*/
1443 osd->orl_width = clip[f->fmt.win.clipcount].c.width;
1444 if (osd->orl_width) {
1445 if (MAX_ORL_NUM) {
1446 osd->orl_en = 1;
1447 osd->orl_cnt = f->fmt.win.clipcount;
1448 } else {
1449 osd->orl_en = 0;
1450 vin_err("VIPP orl is not exist!!\n");
1451 goto osd_reset;
1452 }
1453 } else {
1454 if (MAX_COVER_NUM) {
1455 osd->cover_en = 1;
1456 osd->cover_cnt = f->fmt.win.clipcount;
1457 } else {
1458 osd->cover_en = 0;
1459 vin_err("VIPP cover is not exist!!\n");
1460 goto osd_reset;
1461 }
1462 }
1463
1464 if (osd->orl_en) {
1465 for (i = 0; i < osd->orl_cnt; i++) {
1466 u8 r, g, b;
1467
1468 osd->orl_win[i] = clip[i].c;
1469 osd->rgb_orl[i] = clip[i + osd->orl_cnt].c.top;
1470
1471 r = (osd->rgb_orl[i] >> 16) & 0xff;
1472 g = (osd->rgb_orl[i] >> 8) & 0xff;
1473 b = osd->rgb_orl[i] & 0xff;
1474 __osd_rgb_to_yuv(r, g, b, &osd->yuv_orl[0][i],
1475 &osd->yuv_orl[1][i], &osd->yuv_orl[2][i]);
1476 }
1477 }
1478
1479 if (osd->cover_en) {
1480 for (i = 0; i < osd->cover_cnt; i++) {
1481 u8 r, g, b;
1482
1483 osd->cv_win[i] = clip[i].c;
1484 osd->rgb_cover[i] = clip[i + osd->cover_cnt].c.top;
1485
1486 r = (osd->rgb_cover[i] >> 16) & 0xff;
1487 g = (osd->rgb_cover[i] >> 8) & 0xff;
1488 b = osd->rgb_cover[i] & 0xff;
1489 __osd_rgb_to_yuv(r, g, b, &osd->yuv_cover[0][i],
1490 &osd->yuv_cover[1][i], &osd->yuv_cover[2][i]);
1491
1492 }
1493 }
1494 vfree(clip);
1495 }
1496 osd_reset:
1497 osd->is_set = 0;
1498
1499 return ret;
1500 }
1501
__osd_reg_setup(struct vin_core * vinc,struct vin_osd * osd)1502 static int __osd_reg_setup(struct vin_core *vinc, struct vin_osd *osd)
1503 {
1504 struct vipp_osd_config *osd_cfg = NULL;
1505 struct vipp_osd_para_config *para = NULL;
1506 struct vipp_rgb2yuv_factor rgb2yuv_def = {
1507 .jc0 = 0x00000132,
1508 .jc1 = 0x00000259,
1509 .jc2 = 0x00000075,
1510 .jc3 = 0xffffff53,
1511 .jc4 = 0xfffffead,
1512 .jc5 = 0x00000200,
1513 .jc6 = 0x00000200,
1514 .jc7 = 0xfffffe53,
1515 .jc8 = 0xffffffad,
1516 .jc9 = 0x00000000,
1517 .jc10 = 0x00000080,
1518 .jc11 = 0x00000080,
1519 };
1520 int id = vinc->vipp_sel;
1521 int i;
1522 int act_width;
1523
1524 osd_cfg = kzalloc(sizeof(struct vipp_osd_config), GFP_KERNEL);
1525 if (osd_cfg == NULL) {
1526 vin_err("%s - Alloc of osd_cfg failed\n", __func__);
1527 return -ENOMEM;
1528 }
1529
1530 para = kzalloc(sizeof(struct vipp_osd_para_config), GFP_KERNEL);
1531 if (para == NULL) {
1532 vin_err("%s - Alloc of osd_para failed\n", __func__);
1533 kfree(osd_cfg);
1534 return -ENOMEM;
1535 }
1536
1537 if (osd->overlay_en == 1) {
1538 osd_cfg->osd_argb_mode = osd->overlay_fmt;
1539 osd_cfg->osd_ov_num = osd->overlay_cnt - 1;
1540 osd_cfg->osd_ov_en = 1;
1541 osd_cfg->osd_stat_en = 1;
1542 for (i = 0; i < osd->overlay_cnt; i++) {
1543 if (vinc->hflip)
1544 para->overlay_cfg[i].h_start = vinc->vid_cap.frame.o_width - osd->ov_win[i].width - osd->ov_win[i].left;
1545 else
1546 para->overlay_cfg[i].h_start = osd->ov_win[i].left;
1547 para->overlay_cfg[i].h_end = para->overlay_cfg[i].h_start + osd->ov_win[i].width - 1;
1548
1549 if (vinc->vflip)
1550 para->overlay_cfg[i].v_start = vinc->vid_cap.frame.o_height - osd->ov_win[i].height - osd->ov_win[i].top;
1551 else
1552 para->overlay_cfg[i].v_start = osd->ov_win[i].top;
1553 para->overlay_cfg[i].v_end = para->overlay_cfg[i].v_start + osd->ov_win[i].height - 1;
1554
1555 para->overlay_cfg[i].alpha = osd->global_alpha[i];
1556 para->overlay_cfg[i].inv_en = !osd->inverse_close[i];
1557 para->overlay_cfg[i].inv_th = osd->inv_th;
1558 para->overlay_cfg[i].inv_w_rgn = osd->inv_w_rgn[i];
1559 para->overlay_cfg[i].inv_h_rgn = osd->inv_h_rgn[i];
1560 }
1561 vipp_set_osd_bm_load_addr(id, (unsigned long)osd->ov_mask[osd->ov_set_cnt % 2].dma_addr);
1562 } else {
1563 osd_cfg->osd_ov_num = -1;
1564 }
1565
1566 if (osd->cover_en == 1) {
1567 osd_cfg->osd_cv_num = osd->cover_cnt - 1;
1568 osd_cfg->osd_cv_en = 1;
1569 for (i = 0; i < osd->cover_cnt; i++) {
1570 if (vinc->hflip)
1571 para->cover_cfg[i].h_start = vinc->vid_cap.frame.o_width - osd->cv_win[i].width - osd->cv_win[i].left;
1572 else
1573 para->cover_cfg[i].h_start = osd->cv_win[i].left;
1574 para->cover_cfg[i].h_end = para->cover_cfg[i].h_start + osd->cv_win[i].width - 1;
1575
1576 if (vinc->vflip)
1577 para->cover_cfg[i].v_start = vinc->vid_cap.frame.o_height - osd->cv_win[i].height - osd->cv_win[i].top;
1578 else
1579 para->cover_cfg[i].v_start = osd->cv_win[i].top;
1580 para->cover_cfg[i].v_end = para->cover_cfg[i].v_start + osd->cv_win[i].height - 1;
1581
1582 para->cover_data[i].y = osd->yuv_cover[0][i];
1583 para->cover_data[i].u = osd->yuv_cover[1][i];
1584 para->cover_data[i].v = osd->yuv_cover[2][i];
1585 }
1586 } else {
1587 osd_cfg->osd_cv_num = -1;
1588 }
1589
1590 if (osd->orl_en == 1) {
1591 osd_cfg->osd_orl_num = osd->orl_cnt - 1;
1592 osd_cfg->osd_orl_en = 1;
1593 osd_cfg->osd_orl_width = osd->orl_width;
1594 act_width = 2 * (osd_cfg->osd_orl_width + 1);
1595 for (i = 0; i < osd->orl_cnt; i++) {
1596 if (osd->orl_win[i].height < 2 * act_width)
1597 osd->orl_win[i].height = 2 * act_width;
1598 if (osd->orl_win[i].width < 2 * act_width)
1599 osd->orl_win[i].width = 2 * act_width;
1600
1601 if (vinc->hflip)
1602 para->orl_cfg[i].h_start = vinc->vid_cap.frame.o_width - osd->orl_win[i].width - osd->orl_win[i].left;
1603 else
1604 para->orl_cfg[i].h_start = osd->orl_win[i].left;
1605 para->orl_cfg[i].h_end = para->orl_cfg[i].h_start + osd->orl_win[i].width - 1;
1606
1607 if (vinc->vflip)
1608 para->orl_cfg[i].v_start = vinc->vid_cap.frame.o_height - osd->orl_win[i].height - osd->orl_win[i].top;
1609 else
1610 para->orl_cfg[i].v_start = osd->orl_win[i].top;
1611 para->orl_cfg[i].v_end = para->orl_cfg[i].v_start + osd->orl_win[i].height - 1;
1612
1613 para->orl_data[i].y = osd->yuv_orl[0][i];
1614 para->orl_data[i].u = osd->yuv_orl[1][i];
1615 para->orl_data[i].v = osd->yuv_orl[2][i];
1616 }
1617 } else {
1618 osd_cfg->osd_orl_num = -1;
1619 }
1620
1621 vipp_osd_cfg(id, osd_cfg);
1622 vipp_osd_rgb2yuv(id, &rgb2yuv_def);
1623 vipp_osd_para_cfg(id, para, osd_cfg);
1624 vipp_osd_hvflip(id, vinc->hflip, vinc->vflip);
1625 kfree(osd_cfg);
1626 kfree(para);
1627 return 0;
1628 }
1629
vidioc_overlay(struct file * file,void * __fh,unsigned int on)1630 static int vidioc_overlay(struct file *file, void *__fh, unsigned int on)
1631 {
1632 struct vin_core *vinc = video_drvdata(file);
1633 struct vin_osd *osd = &vinc->vid_cap.osd;
1634 int i;
1635 int ret = 0;
1636
1637 if (!on) {
1638 for (i = 0; i < 2; i++) {
1639 if (osd->ov_mask[i].phy_addr) {
1640 os_mem_free(&vinc->pdev->dev, &osd->ov_mask[i]);
1641 osd->ov_mask[i].phy_addr = NULL;
1642 osd->ov_mask[i].size = 0;
1643 }
1644 }
1645 osd->ov_set_cnt = 0;
1646 osd->overlay_en = 0;
1647 osd->cover_en = 0;
1648 osd->orl_en = 0;
1649 } else {
1650 if (osd->is_set)
1651 return ret;
1652 }
1653
1654 ret = __osd_reg_setup(vinc, osd);
1655 osd->is_set = 1;
1656 return ret;
1657 }
1658
vin_timer_init(struct vin_core * vinc)1659 int vin_timer_init(struct vin_core *vinc)
1660 {
1661 return 0;
1662 }
1663
vin_timer_del(struct vin_core * vinc)1664 void vin_timer_del(struct vin_core *vinc)
1665 {
1666
1667 }
1668
vin_timer_update(struct vin_core * vinc,int ms)1669 void vin_timer_update(struct vin_core *vinc, int ms)
1670 {
1671
1672 }
1673
__vin_sensor_setup_link(struct vin_core * vinc,struct modules_config * module,int i,int en)1674 static int __vin_sensor_setup_link(struct vin_core *vinc, struct modules_config *module,
1675 int i, int en)
1676 {
1677 struct vin_md *vind = dev_get_drvdata(vinc->v4l2_dev->dev);
1678 struct v4l2_subdev *sensor = module->modules.sensor[i].sd;
1679 struct v4l2_subdev *subdev;
1680 struct media_entity *entity = NULL;
1681 struct media_link *link = NULL;
1682 int ret;
1683
1684 if (sensor == NULL)
1685 return -1;
1686
1687 if (vinc->mipi_sel != 0xff)
1688 subdev = vind->mipi[vinc->mipi_sel].sd;
1689 else
1690 subdev = vind->csi[vinc->csi_sel].sd;
1691
1692 entity = &sensor->entity;
1693 list_for_each_entry(link, &entity->links, list) {
1694 if (link->source->entity == entity && link->sink->entity == &subdev->entity)
1695 break;
1696 }
1697 if (link == NULL)
1698 return -1;
1699
1700 if (sensor->entity.stream_count >= 1)
1701 return 0;
1702
1703 vin_log(VIN_LOG_VIDEO, "setup link: [%s] %c> [%s]\n",
1704 sensor->name, en ? '=' : '-', link->sink->entity->name);
1705 if (en)
1706 ret = media_entity_setup_link(link, MEDIA_LNK_FL_ENABLED);
1707 else
1708 ret = __media_entity_setup_link(link, 0);
1709 /*When the this function is called by the close
1710 function, the mutex conflicts with the close mutex,
1711 so the function without the mutex is used.*/
1712
1713 if (ret) {
1714 vin_warn("%s setup link %s fail!\n", sensor->name,
1715 link->sink->entity->name);
1716 return -1;
1717 }
1718 return 0;
1719 }
1720
__csi_isp_setup_link(struct vin_core * vinc,int en)1721 static int __csi_isp_setup_link(struct vin_core *vinc, int en)
1722 {
1723 #ifndef SUPPORT_ISP_TDM
1724 struct vin_md *vind = dev_get_drvdata(vinc->v4l2_dev->dev);
1725 struct v4l2_subdev *csi, *isp;
1726 struct media_link *link = NULL;
1727 int ret;
1728
1729 /*CSI*/
1730 if (vinc->csi_sel == 0xff)
1731 csi = NULL;
1732 else
1733 csi = vind->csi[vinc->csi_sel].sd;
1734
1735 /*ISP*/
1736 if (vinc->isp_sel == 0xff)
1737 isp = NULL;
1738 else
1739 isp = vind->isp[vinc->isp_sel].sd;
1740
1741 if (csi && isp) {
1742 link = media_entity_find_link(&csi->entity.pads[CSI_PAD_SOURCE],
1743 &isp->entity.pads[ISP_PAD_SINK]);
1744 }
1745 if (link == NULL) {
1746 vin_err("%s:media_entity_find_link null\n", __func__);
1747 return -1;
1748 }
1749
1750 if (csi->entity.stream_count >= 1)
1751 return 0;
1752 vin_log(VIN_LOG_MD, "link: source %s sink %s\n",
1753 link->source->entity->name,
1754 link->sink->entity->name);
1755 if (en)
1756 ret = media_entity_setup_link(link, MEDIA_LNK_FL_ENABLED);
1757 else
1758 ret = __media_entity_setup_link(link, 0);
1759 /*When the this function is called by the close
1760 function, the mutex conflicts with the close mutex,
1761 so the function without the mutex is used.*/
1762 if (ret) {
1763 vin_warn("%s setup link %s fail!\n", link->source->entity->name,
1764 link->sink->entity->name);
1765 return -1;
1766 }
1767 #endif
1768 return 0;
1769 }
1770
vidioc_streamon(struct file * file,void * priv,enum v4l2_buf_type i)1771 static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
1772 {
1773 struct vin_core *vinc = video_drvdata(file);
1774 struct vin_vid_cap *cap = &vinc->vid_cap;
1775 int ret = 0;
1776
1777 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1778 ret = -EINVAL;
1779 goto streamon_error;
1780 }
1781
1782 if (vin_streaming(cap)) {
1783 vin_err("video%d has already stream on\n", vinc->id);
1784 ret = -1;
1785 goto streamon_error;
1786 }
1787
1788 ret = vb2_ioctl_streamon(file, priv, i);
1789 if (ret)
1790 goto streamon_error;
1791
1792 if (vinc->large_image == 1) {
1793 #ifdef SUPPORT_PTN
1794 vinc->ptn_cfg.ptn_w = cap->frame.o_width;
1795 vinc->ptn_cfg.ptn_h = cap->frame.o_height;
1796 vinc->ptn_cfg.ptn_mode = 12;
1797 vinc->ptn_cfg.ptn_buf.size = cap->buf_byte_size;
1798 os_mem_alloc(&vinc->pdev->dev, &vinc->ptn_cfg.ptn_buf);
1799 if (vinc->ptn_cfg.ptn_buf.vir_addr == NULL) {
1800 vin_err("ptn buffer 0x%x alloc failed!\n", cap->buf_byte_size);
1801 return -ENOMEM;
1802 }
1803 csic_dma_buffer_address(vinc->vipp_sel, CSI_BUF_0_A, (unsigned long)vinc->ptn_cfg.ptn_buf.dma_addr);
1804 #endif
1805 }
1806 #if 0
1807 schedule_work(&vinc->vid_cap.s_stream_task);
1808 #else
1809 mutex_lock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
1810 vin_timer_init(cap->vinc);
1811 ret = vin_pipeline_call(cap->vinc, set_stream, &cap->pipe, cap->vinc->stream_idx);
1812 if (ret < 0)
1813 vin_err("video%d %s error!\n", vinc->id, __func__);
1814 set_bit(VIN_STREAM, &cap->state);
1815 /*set saved exp and gain for reopen, you can call the api in sensor_reg_init*/
1816 /*
1817 if (cap->vinc->exp_gain.exp_val && cap->vinc->exp_gain.gain_val) {
1818 v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], core, ioctl,
1819 VIDIOC_VIN_SENSOR_EXP_GAIN, &cap->vinc->exp_gain);
1820 }
1821 */
1822 mutex_unlock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
1823 #endif
1824 streamon_error:
1825
1826 return ret;
1827 }
1828
vin_queue_free(struct file * file)1829 static void vin_queue_free(struct file *file)
1830 {
1831 struct video_device *vdev = video_devdata(file);
1832
1833 if (file->private_data == vdev->queue->owner) {
1834 vb2_queue_release(vdev->queue);
1835 vdev->queue->owner = NULL;
1836 }
1837
1838 }
1839
vidioc_streamoff(struct file * file,void * priv,enum v4l2_buf_type i)1840 static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
1841 {
1842 struct vin_core *vinc = video_drvdata(file);
1843 struct vin_md *vind = dev_get_drvdata(vinc->v4l2_dev->dev);
1844 struct vin_vid_cap *cap = &vinc->vid_cap;
1845 struct modules_config *module = &vind->modules[vinc->sensor_sel];
1846 int valid_idx = module->sensors.valid_idx;
1847 int ret = 0;
1848 if (!vin_streaming(cap)) {
1849 vin_err("video%d has already stream off\n", vinc->id);
1850 goto streamoff_error;
1851 }
1852 vin_timer_del(vinc);
1853
1854 mutex_lock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
1855 clear_bit(VIN_STREAM, &cap->state);
1856 vin_pipeline_call(vinc, set_stream, &cap->pipe, 0);
1857 set_bit(VIN_LPM, &cap->state);
1858 __csi_isp_setup_link(vinc, 0);
1859 __vin_sensor_setup_link(vinc, module, valid_idx, 0);
1860 mutex_unlock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
1861
1862 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
1863 ret = -EINVAL;
1864 goto streamoff_error;
1865 }
1866
1867 ret = vb2_ioctl_streamoff(file, priv, i);
1868 if (ret != 0) {
1869 vin_err("video%d stream off error!\n", vinc->id);
1870 goto streamoff_error;
1871 }
1872 vin_queue_free(file);
1873 streamoff_error:
1874
1875 return ret;
1876 }
1877
vidioc_enum_input(struct file * file,void * priv,struct v4l2_input * inp)1878 static int vidioc_enum_input(struct file *file, void *priv,
1879 struct v4l2_input *inp)
1880 {
1881 if (inp->index != 0)
1882 return -EINVAL;
1883
1884 inp->type = V4L2_INPUT_TYPE_CAMERA;
1885 inp->std = V4L2_STD_UNKNOWN;
1886 strcpy(inp->name, "sunxi-vin");
1887
1888 return 0;
1889 }
1890
vidioc_g_input(struct file * file,void * priv,unsigned int * i)1891 static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1892 {
1893 struct vin_core *vinc = video_drvdata(file);
1894
1895 if (vinc->sensor_sel == vinc->rear_sensor)
1896 *i = 0;
1897 else
1898 *i = 1;
1899
1900 return 0;
1901 }
1902
__vin_actuator_set_power(struct v4l2_subdev * sd,int on)1903 static int __vin_actuator_set_power(struct v4l2_subdev *sd, int on)
1904 {
1905 int *use_count;
1906 int ret;
1907
1908 if (sd == NULL)
1909 return -ENXIO;
1910
1911 use_count = &sd->entity.use_count;
1912 if (on && (*use_count)++ > 0)
1913 return 0;
1914 else if (!on && (*use_count == 0 || --(*use_count) > 0))
1915 return 0;
1916 ret = v4l2_subdev_call(sd, core, ioctl, ACT_SOFT_PWDN, 0);
1917
1918 return ret != -ENOIOCTLCMD ? ret : 0;
1919 }
1920
vidioc_s_input(struct file * file,void * priv,unsigned int i)1921 static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
1922 {
1923 struct vin_core *vinc = video_drvdata(file);
1924 struct vin_md *vind = dev_get_drvdata(vinc->v4l2_dev->dev);
1925 struct vin_vid_cap *cap = &vinc->vid_cap;
1926 struct modules_config *module = NULL;
1927 struct sensor_instance *inst = NULL;
1928 struct sensor_info *info = NULL;
1929 struct mipi_dev *mipi = NULL;
1930 int valid_idx = -1;
1931 int ret;
1932
1933 i = i > 1 ? 0 : i;
1934
1935 if (i == 0)
1936 vinc->sensor_sel = vinc->rear_sensor;
1937 else
1938 vinc->sensor_sel = vinc->front_sensor;
1939
1940 module = &vind->modules[vinc->sensor_sel];
1941 valid_idx = module->sensors.valid_idx;
1942
1943 if (valid_idx == NO_VALID_SENSOR) {
1944 vin_err("there is no valid sensor\n");
1945 return -EINVAL;
1946 }
1947
1948 if (__vin_sensor_setup_link(vinc, module, valid_idx, 1) < 0) {
1949 vin_err("sensor setup link failed\n");
1950 return -EINVAL;
1951 }
1952 if (__csi_isp_setup_link(vinc, 1) < 0) {
1953 vin_err("csi&isp setup link failed\n");
1954 return -EINVAL;
1955 }
1956 inst = &module->sensors.inst[valid_idx];
1957
1958 sunxi_isp_sensor_type(cap->pipe.sd[VIN_IND_ISP], inst->is_isp_used);
1959 vinc->support_raw = inst->is_isp_used;
1960
1961 ret = vin_pipeline_call(vinc, open, &cap->pipe, &cap->vdev.entity, true);
1962 if (ret < 0) {
1963 vin_err("vin pipeline open failed (%d)!\n", ret);
1964 return ret;
1965 }
1966
1967 if (module->modules.act[valid_idx].sd != NULL) {
1968 cap->pipe.sd[VIN_IND_ACTUATOR] = module->modules.act[valid_idx].sd;
1969 ret = __vin_actuator_set_power(cap->pipe.sd[VIN_IND_ACTUATOR], 1);
1970 if (ret < 0) {
1971 vin_err("actutor power off failed (%d)!\n", ret);
1972 return ret;
1973 }
1974 }
1975
1976 if (module->modules.flash.sd != NULL)
1977 cap->pipe.sd[VIN_IND_FLASH] = module->modules.flash.sd;
1978
1979 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_ISP], core, init, 1);
1980 if (ret < 0) {
1981 vin_err("ISP init error at %s\n", __func__);
1982 return ret;
1983 }
1984
1985 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_SCALER], core, init, 1);
1986 if (ret < 0) {
1987 vin_err("SCALER init error at %s\n", __func__);
1988 return ret;
1989 }
1990
1991 /*save exp and gain for reopen, sensor init may reset gain to 0, so save before init!*/
1992 info = container_of(cap->pipe.sd[VIN_IND_SENSOR], struct sensor_info, sd);
1993 if (info) {
1994 vinc->exp_gain.exp_val = info->exp;
1995 vinc->exp_gain.gain_val = info->gain;
1996 vinc->stream_idx = info->stream_seq + 1;
1997 }
1998
1999 if (cap->pipe.sd[VIN_IND_MIPI] != NULL) {
2000 mipi = container_of(cap->pipe.sd[VIN_IND_MIPI], struct mipi_dev, subdev);
2001 if (mipi)
2002 mipi->sensor_flags = vinc->sensor_sel;
2003 }
2004
2005 if (!vinc->ptn_cfg.ptn_en) {
2006 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], core, init, 1);
2007 if (ret) {
2008 vin_err("sensor initial error when selecting target device!\n");
2009 return ret;
2010 }
2011 }
2012 clear_bit(VIN_LPM, &cap->state);
2013
2014 /*setup the current ctrl value*/
2015 /*
2016 v4l2_ctrl_handler_setup(&vinc->vid_cap.ctrl_handler);
2017 v4l2_ctrl_handler_setup(cap->pipe.sd[VIN_IND_SENSOR]->ctrl_handler);
2018 */
2019
2020 vinc->hflip = inst->hflip;
2021 vinc->vflip = inst->vflip;
2022
2023 return ret;
2024 }
2025
2026 static const char *const sensor_info_type[] = {
2027 "YUV",
2028 "RAW",
2029 NULL,
2030 };
2031
vidioc_g_parm(struct file * file,void * priv,struct v4l2_streamparm * parms)2032 static int vidioc_g_parm(struct file *file, void *priv,
2033 struct v4l2_streamparm *parms)
2034 {
2035 struct vin_core *vinc = video_drvdata(file);
2036 struct vin_vid_cap *cap = &vinc->vid_cap;
2037
2038 int ret;
2039
2040 ret = sensor_g_parm(cap->pipe.sd[VIN_IND_SENSOR], parms);
2041 if (ret < 0)
2042 vin_warn("v4l2 sub device g_parm fail!\n");
2043
2044 return ret;
2045
2046 }
2047
vidioc_s_parm(struct file * file,void * priv,struct v4l2_streamparm * parms)2048 static int vidioc_s_parm(struct file *file, void *priv,
2049 struct v4l2_streamparm *parms)
2050 {
2051 struct vin_core *vinc = video_drvdata(file);
2052 struct vin_vid_cap *cap = &vinc->vid_cap;
2053 struct sensor_instance *inst = get_valid_sensor(vinc);
2054 int ret = 0;
2055
2056 if (parms->parm.capture.capturemode != V4L2_MODE_VIDEO &&
2057 parms->parm.capture.capturemode != V4L2_MODE_IMAGE &&
2058 parms->parm.capture.capturemode != V4L2_MODE_PREVIEW) {
2059 parms->parm.capture.capturemode = V4L2_MODE_PREVIEW;
2060 }
2061
2062 cap->capture_mode = parms->parm.capture.capturemode;
2063 vinc->large_image = parms->parm.capture.reserved[2];
2064
2065 if (WARN_ON(!cap->pipe.sd[VIN_IND_SENSOR] || !cap->pipe.sd[VIN_IND_CSI]))
2066 return -EINVAL;
2067
2068 ret = sensor_s_parm(cap->pipe.sd[VIN_IND_SENSOR], parms);
2069 if (ret < 0)
2070 vin_warn("v4l2 subdev sensor s_parm error!\n");
2071
2072 ret = sunxi_csi_subdev_s_parm(cap->pipe.sd[VIN_IND_CSI], parms);
2073 if (ret < 0)
2074 vin_warn("v4l2 subdev csi s_parm error!\n");
2075
2076 if (inst->is_isp_used && cap->pipe.sd[VIN_IND_ISP]) {
2077 ret = sunxi_isp_s_parm(cap->pipe.sd[VIN_IND_ISP], parms);
2078 if (ret < 0)
2079 vin_warn("v4l2 subdev isp s_parm error!\n");
2080 }
2081
2082 return ret;
2083 }
2084
__vin_sensor_line2time(struct v4l2_subdev * sd,u32 exp_line)2085 static int __vin_sensor_line2time(struct v4l2_subdev *sd, u32 exp_line)
2086 {
2087 struct sensor_info *info = to_state(sd);
2088 u32 overflow = 0xffffffff / 1000000, pclk = 0;
2089 int exp_time = 0;
2090
2091 if ((exp_line / 16) > overflow) {
2092 exp_line = exp_line / 16;
2093 pclk = info->current_wins->pclk / 1000000;
2094 } else if ((exp_line / 16) > (overflow / 10)) {
2095 exp_line = exp_line * 10 / 16;
2096 pclk = info->current_wins->pclk / 100000;
2097 } else if ((exp_line / 16) > (overflow / 100)) {
2098 exp_line = exp_line * 100 / 16;
2099 pclk = info->current_wins->pclk / 10000;
2100 } else if ((exp_line / 16) > (overflow / 1000)) {
2101 exp_line = exp_line * 1000 / 16;
2102 pclk = info->current_wins->pclk / 1000;
2103 } else {
2104 exp_line = exp_line * 10000 / 16;
2105 pclk = info->current_wins->pclk / 100;
2106 }
2107
2108 if (pclk)
2109 exp_time = exp_line * info->current_wins->hts / pclk;
2110
2111 return exp_time;
2112 }
2113
__vin_sensor_set_af_win(struct vin_vid_cap * cap)2114 static int __vin_sensor_set_af_win(struct vin_vid_cap *cap)
2115 {
2116 struct vin_pipeline *pipe = &cap->pipe;
2117 struct v4l2_win_setting af_win;
2118 int ret = 0;
2119
2120 af_win.coor.x1 = cap->af_win[0]->val;
2121 af_win.coor.y1 = cap->af_win[1]->val;
2122 af_win.coor.x2 = cap->af_win[2]->val;
2123 af_win.coor.y2 = cap->af_win[3]->val;
2124
2125 ret = v4l2_subdev_call(pipe->sd[VIN_IND_SENSOR],
2126 core, ioctl, SET_AUTO_FOCUS_WIN, &af_win);
2127 return ret;
2128 }
2129
__vin_sensor_set_ae_win(struct vin_vid_cap * cap)2130 static int __vin_sensor_set_ae_win(struct vin_vid_cap *cap)
2131 {
2132 struct vin_pipeline *pipe = &cap->pipe;
2133 struct v4l2_win_setting ae_win;
2134 int ret = 0;
2135
2136 ae_win.coor.x1 = cap->ae_win[0]->val;
2137 ae_win.coor.y1 = cap->ae_win[1]->val;
2138 ae_win.coor.x2 = cap->ae_win[2]->val;
2139 ae_win.coor.y2 = cap->ae_win[3]->val;
2140 ret = v4l2_subdev_call(pipe->sd[VIN_IND_SENSOR],
2141 core, ioctl, SET_AUTO_EXPOSURE_WIN, &ae_win);
2142 return ret;
2143 }
2144
vidioc_sync_ctrl(struct file * file,struct v4l2_fh * fh,struct csi_sync_ctrl * sync)2145 int vidioc_sync_ctrl(struct file *file, struct v4l2_fh *fh,
2146 struct csi_sync_ctrl *sync)
2147 {
2148 struct vin_core *vinc = video_drvdata(file);
2149
2150 if (!sync->type) {
2151 csic_prs_sync_en_cfg(vinc->csi_sel, sync);
2152 csic_prs_sync_cfg(vinc->csi_sel, sync);
2153 csic_prs_sync_wait_N(vinc->csi_sel, sync);
2154 csic_prs_sync_wait_M(vinc->csi_sel, sync);
2155 csic_frame_cnt_enable(vinc->vipp_sel);
2156 csic_dma_frm_cnt(vinc->vipp_sel, sync);
2157 csic_prs_sync_en(vinc->csi_sel, sync);
2158 } else {
2159 csic_prs_xs_en(vinc->csi_sel, sync);
2160 csic_prs_xs_period_len_register(vinc->csi_sel, sync);
2161 }
2162 return 0;
2163 }
2164
vidioc_set_top_clk(struct file * file,struct v4l2_fh * fh,struct vin_top_clk * clk)2165 static int vidioc_set_top_clk(struct file *file, struct v4l2_fh *fh,
2166 struct vin_top_clk *clk)
2167 {
2168 struct vin_core *vinc = video_drvdata(file);
2169
2170 vinc->vin_clk = clk->clk_rate;
2171
2172 return 0;
2173 }
2174
vidioc_set_fps_ds(struct file * file,struct v4l2_fh * fh,struct vin_fps_ds * fps_down_sample)2175 static int vidioc_set_fps_ds(struct file *file, struct v4l2_fh *fh,
2176 struct vin_fps_ds *fps_down_sample)
2177 {
2178 struct vin_core *vinc = video_drvdata(file);
2179
2180 vinc->fps_ds = fps_down_sample->fps_ds;
2181
2182 return 0;
2183 }
2184
vidioc_set_isp_debug(struct file * file,struct v4l2_fh * fh,struct isp_debug_mode * isp_debug)2185 static int vidioc_set_isp_debug(struct file *file, struct v4l2_fh *fh,
2186 struct isp_debug_mode *isp_debug)
2187 {
2188 struct vin_core *vinc = video_drvdata(file);
2189
2190 vinc->isp_dbg = *isp_debug;
2191 sunxi_isp_debug(vinc->vid_cap.pipe.sd[VIN_IND_ISP], isp_debug);
2192
2193 return 0;
2194 }
2195
vidioc_vin_ptn_config(struct file * file,struct v4l2_fh * fh,struct vin_pattern_config * ptn)2196 static int vidioc_vin_ptn_config(struct file *file, struct v4l2_fh *fh,
2197 struct vin_pattern_config *ptn)
2198 {
2199 #ifdef SUPPORT_PTN
2200 struct vin_core *vinc = video_drvdata(file);
2201 struct csi_dev *csi = v4l2_get_subdevdata(vinc->vid_cap.pipe.sd[VIN_IND_CSI]);
2202 int ret = 0;
2203
2204 if (!csi)
2205 return -ENODEV;
2206
2207 if (ptn->ptn_en) {
2208 vinc->ptn_cfg.ptn_en = 1;
2209 vinc->ptn_cfg.ptn_w = ptn->ptn_w;
2210 vinc->ptn_cfg.ptn_h = ptn->ptn_h;
2211 vinc->ptn_cfg.ptn_mode = 12;
2212 vinc->ptn_cfg.ptn_buf.size = ptn->ptn_size;
2213 vinc->ptn_cfg.ptn_type = ptn->ptn_type;
2214 sunxi_isp_ptn(vinc->vid_cap.pipe.sd[VIN_IND_ISP], vinc->ptn_cfg.ptn_type);
2215 switch (ptn->ptn_fmt) {
2216 case V4L2_PIX_FMT_SBGGR8:
2217 case V4L2_PIX_FMT_SGBRG8:
2218 case V4L2_PIX_FMT_SGRBG8:
2219 case V4L2_PIX_FMT_SRGGB8:
2220 vinc->ptn_cfg.ptn_dw = 0;
2221 csi->csi_fmt->data_width = 8;
2222 break;
2223 case V4L2_PIX_FMT_SBGGR10:
2224 case V4L2_PIX_FMT_SGBRG10:
2225 case V4L2_PIX_FMT_SGRBG10:
2226 case V4L2_PIX_FMT_SRGGB10:
2227 vinc->ptn_cfg.ptn_dw = 1;
2228 csi->csi_fmt->data_width = 10;
2229 break;
2230 case V4L2_PIX_FMT_SBGGR12:
2231 case V4L2_PIX_FMT_SGBRG12:
2232 case V4L2_PIX_FMT_SGRBG12:
2233 case V4L2_PIX_FMT_SRGGB12:
2234 vinc->ptn_cfg.ptn_dw = 2;
2235 csi->csi_fmt->data_width = 12;
2236 break;
2237 default:
2238 vinc->ptn_cfg.ptn_dw = 2;
2239 csi->csi_fmt->data_width = 12;
2240 break;
2241 }
2242 csi->bus_info.bus_if = V4L2_MBUS_PARALLEL;
2243
2244 if (ptn->ptn_addr) {
2245 if (vinc->ptn_cfg.ptn_buf.vir_addr == NULL)
2246 os_mem_alloc(&vinc->pdev->dev, &vinc->ptn_cfg.ptn_buf);
2247 if (vinc->ptn_cfg.ptn_buf.vir_addr == NULL) {
2248 vin_err("ptn buffer 0x%x alloc failed!\n", ptn->ptn_size);
2249 return -ENOMEM;
2250 }
2251
2252 ret = copy_from_user(vinc->ptn_cfg.ptn_buf.vir_addr, ptn->ptn_addr, ptn->ptn_size);
2253 if (ret < 0) {
2254 vin_err("copy ptn buffer from usr error!\n");
2255 return ret;
2256 }
2257 }
2258 } else {
2259 vinc->ptn_cfg.ptn_en = 0;
2260 os_mem_free(&vinc->pdev->dev, &vinc->ptn_cfg.ptn_buf);
2261 }
2262 #endif
2263 return 0;
2264 }
2265
vidioc_vin_set_reset_time(struct file * file,struct v4l2_fh * fh,struct vin_reset_time * time)2266 static int vidioc_vin_set_reset_time(struct file *file, struct v4l2_fh *fh,
2267 struct vin_reset_time *time)
2268 {
2269 struct vin_core *vinc = video_drvdata(file);
2270 struct csi_dev *csi = v4l2_get_subdevdata(vinc->vid_cap.pipe.sd[VIN_IND_CSI]);
2271
2272 csi->reset_time = time->reset_time;
2273
2274 return 0;
2275 }
2276
vidioc_set_parser_fps(struct file * file,struct v4l2_fh * fh,struct parser_fps_ds * parser_fps_ds)2277 static int vidioc_set_parser_fps(struct file *file, struct v4l2_fh *fh,
2278 struct parser_fps_ds *parser_fps_ds)
2279 {
2280 struct vin_core *vinc = video_drvdata(file);
2281 struct csi_dev *csi = v4l2_get_subdevdata(vinc->vid_cap.pipe.sd[VIN_IND_CSI]);
2282
2283 csi->prs_fps_ds.ch0_fps_ds = parser_fps_ds->ch0_fps_ds & 0xf;
2284 csi->prs_fps_ds.ch1_fps_ds = parser_fps_ds->ch1_fps_ds & 0xf;
2285 csi->prs_fps_ds.ch2_fps_ds = parser_fps_ds->ch2_fps_ds & 0xf;
2286 csi->prs_fps_ds.ch3_fps_ds = parser_fps_ds->ch3_fps_ds & 0xf;
2287
2288 return 0;
2289 }
2290
2291 /* must set after VIDIOC_S_PARM and before VIDIOC_S_FMT */
vidioc_set_sensor_isp_cfg(struct file * file,struct v4l2_fh * fh,struct sensor_isp_cfg * sensor_isp_cfg)2292 static int vidioc_set_sensor_isp_cfg(struct file *file, struct v4l2_fh *fh,
2293 struct sensor_isp_cfg *sensor_isp_cfg)
2294 {
2295 struct vin_core *vinc = video_drvdata(file);
2296 struct isp_dev *isp = v4l2_get_subdevdata(vinc->vid_cap.pipe.sd[VIN_IND_ISP]);
2297 struct v4l2_subdev *sd = vinc->vid_cap.pipe.sd[VIN_IND_SENSOR];
2298 struct sensor_info *info = container_of(sd, struct sensor_info, sd);
2299
2300 isp->large_image = sensor_isp_cfg->large_image;
2301 info->isp_wdr_mode = sensor_isp_cfg->isp_wdr_mode;
2302
2303 return 0;
2304 }
2305
vin_param_handler(struct file * file,void * priv,bool valid_prio,unsigned int cmd,void * param)2306 static long vin_param_handler(struct file *file, void *priv,
2307 bool valid_prio, unsigned int cmd, void *param)
2308 {
2309 int ret = 0;
2310 struct v4l2_fh *fh = (struct v4l2_fh *)priv;
2311
2312 switch (cmd) {
2313 case VIDIOC_ISP_EXIF_REQ:
2314 break;
2315 case VIDIOC_SYNC_CTRL:
2316 ret = vidioc_sync_ctrl(file, fh, param);
2317 break;
2318 case VIDIOC_SET_TOP_CLK:
2319 ret = vidioc_set_top_clk(file, fh, param);
2320 break;
2321 case VIDIOC_SET_FPS_DS:
2322 ret = vidioc_set_fps_ds(file, fh, param);
2323 break;
2324 case VIDIOC_ISP_DEBUG:
2325 ret = vidioc_set_isp_debug(file, fh, param);
2326 break;
2327 case VIDIOC_VIN_PTN_CFG:
2328 ret = vidioc_vin_ptn_config(file, fh, param);
2329 break;
2330 case VIDIOC_VIN_RESET_TIME:
2331 ret = vidioc_vin_set_reset_time(file, fh, param);
2332 break;
2333 case VIDIOC_SET_PARSER_FPS:
2334 ret = vidioc_set_parser_fps(file, fh, param);
2335 break;
2336 case VIDIOC_SET_SENSOR_ISP_CFG:
2337 ret = vidioc_set_sensor_isp_cfg(file, fh, param);
2338 break;
2339 default:
2340 ret = -ENOTTY;
2341 }
2342 return ret;
2343 }
2344
vin_subscribe_event(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)2345 static int vin_subscribe_event(struct v4l2_fh *fh,
2346 const struct v4l2_event_subscription *sub)
2347 {
2348 if (sub->type == V4L2_EVENT_CTRL)
2349 return v4l2_ctrl_subscribe_event(fh, sub);
2350 else
2351 return v4l2_event_subscribe(fh, sub, 1, NULL);
2352 }
2353
vin_open(struct file * file)2354 static int vin_open(struct file *file)
2355 {
2356 struct vin_core *vinc = video_drvdata(file);
2357 struct vin_vid_cap *cap = &vinc->vid_cap;
2358
2359 if (vin_busy(cap)) {
2360 vin_err("video%d open busy\n", vinc->id);
2361 return -EBUSY;
2362 }
2363 mutex_lock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
2364 set_bit(VIN_LPM, &cap->state);
2365 set_bit(VIN_BUSY, &cap->state);
2366 v4l2_fh_open(file);/* create event queue */
2367
2368 #ifdef CONFIG_DEVFREQ_DRAM_FREQ_WITH_SOFT_NOTIFY
2369 dramfreq_master_access(MASTER_CSI, true);
2370 #endif
2371
2372 vin_log(VIN_LOG_VIDEO, "video%d open\n", vinc->id);
2373 mutex_unlock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
2374 return 0;
2375 }
2376
vin_close(struct file * file)2377 static int vin_close(struct file *file)
2378 {
2379 struct video_device *vdev = video_devdata(file);
2380 struct vin_core *vinc = video_drvdata(file);
2381 struct vin_md *vind = dev_get_drvdata(vinc->v4l2_dev->dev);
2382 struct vin_vid_cap *cap = &vinc->vid_cap;
2383 struct modules_config *module = &vind->modules[vinc->sensor_sel];
2384 int valid_idx = module->sensors.valid_idx;
2385 int ret;
2386 if (!vin_busy(cap)) {
2387 vin_warn("video%d have been closed!\n", vinc->id);
2388 return 0;
2389 }
2390
2391 if (vin_streaming(cap))
2392 vin_timer_del(vinc);
2393
2394 mutex_lock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
2395 if (!cap->pipe.sd[VIN_IND_SENSOR] || !cap->pipe.sd[VIN_IND_SENSOR]->entity.use_count) {
2396 mutex_unlock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
2397 vb2_fop_release(file);
2398 set_bit(VIN_LPM, &cap->state);
2399 clear_bit(VIN_BUSY, &cap->state);
2400 if (cap->pipe.sd[VIN_IND_SENSOR])
2401 vin_err("%s is not used, video%d cannot be close!\n", cap->pipe.sd[VIN_IND_SENSOR]->name, vinc->id);
2402 return -1;
2403 }
2404
2405 if (vin_streaming(cap)) {
2406 clear_bit(VIN_STREAM, &cap->state);
2407 vin_pipeline_call(vinc, set_stream, &cap->pipe, 0);
2408 vb2_ioctl_streamoff(file, NULL, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE);
2409 }
2410
2411 if (!vin_lpm(cap)) {
2412 set_bit(VIN_LPM, &cap->state);
2413 __csi_isp_setup_link(vinc, 0);
2414 __vin_sensor_setup_link(vinc, module, valid_idx, 0);
2415 }
2416
2417 if (cap->pipe.sd[VIN_IND_ACTUATOR] != NULL) {
2418 ret = __vin_actuator_set_power(cap->pipe.sd[VIN_IND_ACTUATOR], 0);
2419 if (ret < 0)
2420 vin_err("actutor power off failed (%d)!\n", ret);
2421 }
2422
2423 if (cap->pipe.sd[VIN_IND_FLASH] != NULL)
2424 io_set_flash_ctrl(cap->pipe.sd[VIN_IND_FLASH], SW_CTRL_FLASH_OFF);
2425
2426 ret = vin_pipeline_call(vinc, close, &cap->pipe);
2427 if (ret)
2428 vin_err("vin pipeline close failed!\n");
2429
2430 v4l2_subdev_call(cap->pipe.sd[VIN_IND_ISP], core, init, 0);
2431
2432 #ifdef SUPPORT_PTN
2433 if ((vinc->large_image == 2) && vinc->ptn_cfg.ptn_en) {
2434 os_mem_free(&vinc->pdev->dev, &vinc->ptn_cfg.ptn_buf);
2435 vinc->ptn_cfg.ptn_en = 0;
2436 }
2437 #endif
2438 /*vb2_fop_release will use graph_mutex*/
2439 mutex_unlock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
2440
2441 if (file->private_data == vdev->queue->owner) {
2442 vdev->queue->owner = NULL;
2443 }
2444 ret = vb2_fop_release(file); /*vb2_queue_release(&cap->vb_vidq);*/
2445 #ifdef CONFIG_DEVFREQ_DRAM_FREQ_WITH_SOFT_NOTIFY
2446 dramfreq_master_access(MASTER_CSI, false);
2447 #endif
2448 clear_bit(VIN_BUSY, &cap->state);
2449 vin_log(VIN_LOG_VIDEO, "video%d close\n", vinc->id);
2450 return 0;
2451 }
2452
vin_poll(struct file * file,poll_table * wait)2453 static unsigned int vin_poll(struct file *file, poll_table *wait)
2454 {
2455 struct vin_core *vinc = video_drvdata(file);
2456 struct vin_vid_cap *cap = &vinc->vid_cap;
2457
2458 if (!vin_streaming(cap))
2459 return 0;
2460
2461 return vb2_fop_poll(file, wait);
2462 }
2463
vin_try_ctrl(struct v4l2_ctrl * ctrl)2464 static int vin_try_ctrl(struct v4l2_ctrl *ctrl)
2465 {
2466 /*
2467 * to cheat control framework, because of when ctrl->cur.val == ctrl->val
2468 * s_ctrl would not be called
2469 */
2470 if ((ctrl->minimum == 0) && (ctrl->maximum == 1)) {
2471 if (ctrl->val)
2472 ctrl->cur.val = 0;
2473 else
2474 ctrl->cur.val = 1;
2475 } else {
2476 if (ctrl->val == ctrl->maximum)
2477 ctrl->cur.val = ctrl->val - 1;
2478 else
2479 ctrl->cur.val = ctrl->val + 1;
2480 }
2481
2482 /*
2483 * to cheat control framework, because of when ctrl->flags is
2484 * V4L2_CTRL_FLAG_VOLATILE, s_ctrl would not be called
2485 */
2486 switch (ctrl->id) {
2487 case V4L2_CID_EXPOSURE:
2488 case V4L2_CID_EXPOSURE_ABSOLUTE:
2489 case V4L2_CID_GAIN:
2490 if (ctrl->val != ctrl->cur.val)
2491 ctrl->flags &= ~V4L2_CTRL_FLAG_VOLATILE;
2492 break;
2493 default:
2494 break;
2495 }
2496 return 0;
2497 }
vin_g_volatile_ctrl(struct v4l2_ctrl * ctrl)2498 static int vin_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
2499 {
2500 struct vin_vid_cap *cap = container_of(ctrl->handler, struct vin_vid_cap, ctrl_handler);
2501 struct sensor_instance *inst = get_valid_sensor(cap->vinc);
2502 struct v4l2_subdev *sensor = cap->pipe.sd[VIN_IND_SENSOR];
2503 struct v4l2_subdev *flash = cap->pipe.sd[VIN_IND_FLASH];
2504 struct v4l2_control c;
2505 int ret = 0;
2506
2507 c.id = ctrl->id;
2508 if (inst->is_isp_used && inst->is_bayer_raw) {
2509 switch (ctrl->id) {
2510 case V4L2_CID_EXPOSURE:
2511 v4l2_g_ctrl(sensor->ctrl_handler, &c);
2512 ctrl->val = c.value;
2513 break;
2514 case V4L2_CID_EXPOSURE_ABSOLUTE:
2515 c.id = V4L2_CID_EXPOSURE;
2516 v4l2_g_ctrl(sensor->ctrl_handler, &c);
2517 ctrl->val = __vin_sensor_line2time(sensor, c.value);
2518 break;
2519 case V4L2_CID_GAIN:
2520 v4l2_g_ctrl(sensor->ctrl_handler, &c);
2521 ctrl->val = c.value;
2522 break;
2523 case V4L2_CID_HOR_VISUAL_ANGLE:
2524 case V4L2_CID_VER_VISUAL_ANGLE:
2525 case V4L2_CID_FOCUS_LENGTH:
2526 case V4L2_CID_3A_LOCK:
2527 case V4L2_CID_AUTO_FOCUS_STATUS: /*Read-Only*/
2528 break;
2529 case V4L2_CID_SENSOR_TYPE:
2530 ctrl->val = inst->is_bayer_raw;
2531 break;
2532 default:
2533 return -EINVAL;
2534 }
2535 return ret;
2536 } else {
2537 switch (ctrl->id) {
2538 case V4L2_CID_SENSOR_TYPE:
2539 c.value = inst->is_bayer_raw;
2540 break;
2541 case V4L2_CID_FLASH_LED_MODE:
2542 ret = v4l2_g_ctrl(flash->ctrl_handler, &c);
2543 break;
2544 case V4L2_CID_AUTO_FOCUS_STATUS:
2545 ret = v4l2_g_ctrl(sensor->ctrl_handler, &c);
2546 if (c.value != V4L2_AUTO_FOCUS_STATUS_BUSY)
2547 sunxi_flash_stop(flash);
2548 break;
2549 default:
2550 ret = v4l2_g_ctrl(sensor->ctrl_handler, &c);
2551 break;
2552 }
2553 ctrl->val = c.value;
2554 if (ret < 0)
2555 vin_warn("v4l2 sub device g_ctrl fail!\n");
2556 }
2557 return ret;
2558 }
2559
sensor_flip_option(struct vin_vid_cap * cap,struct v4l2_control c)2560 int sensor_flip_option(struct vin_vid_cap *cap, struct v4l2_control c)
2561 {
2562 struct v4l2_subdev *isp = cap->pipe.sd[VIN_IND_ISP];
2563 struct v4l2_subdev *csi = cap->pipe.sd[VIN_IND_CSI];
2564 struct v4l2_subdev *sensor = cap->pipe.sd[VIN_IND_SENSOR];
2565 struct isp_dev *isp_device = v4l2_get_subdevdata(isp);
2566 struct csi_dev *csi_device = v4l2_get_subdevdata(csi);
2567 struct vin_md *vind = dev_get_drvdata(isp->v4l2_dev->dev);
2568 struct vin_core *vinc = NULL;
2569 struct prs_cap_mode mode = {.mode = VCAP};
2570 unsigned int isp_stream_count;
2571 int i = 0;
2572 int input_seq = 0;
2573 int sensor_fmt_code = 0;
2574 int ret;
2575 mutex_lock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
2576 isp_stream_count = isp_device->subdev.entity.stream_count;
2577 isp_device->subdev.entity.stream_count = 0;
2578 csic_prs_capture_stop(csi_device->id);
2579
2580 ret = v4l2_s_ctrl(NULL, sensor->ctrl_handler, &c);
2581 v4l2_subdev_call(sensor, core, ioctl, VIDIOC_VIN_GET_SENSOR_CODE, &sensor_fmt_code);
2582 switch (sensor_fmt_code) {
2583 case MEDIA_BUS_FMT_SBGGR8_1X8:
2584 case MEDIA_BUS_FMT_SBGGR10_1X10:
2585 case MEDIA_BUS_FMT_SBGGR12_1X12:
2586 input_seq = ISP_BGGR;
2587 break;
2588 case MEDIA_BUS_FMT_SGBRG8_1X8:
2589 case MEDIA_BUS_FMT_SGBRG10_1X10:
2590 case MEDIA_BUS_FMT_SGBRG12_1X12:
2591 input_seq = ISP_GBRG;
2592 break;
2593 case MEDIA_BUS_FMT_SGRBG8_1X8:
2594 case MEDIA_BUS_FMT_SGRBG10_1X10:
2595 case MEDIA_BUS_FMT_SGRBG12_1X12:
2596 input_seq = ISP_GRBG;
2597 break;
2598 case MEDIA_BUS_FMT_SRGGB8_1X8:
2599 case MEDIA_BUS_FMT_SRGGB10_1X10:
2600 case MEDIA_BUS_FMT_SRGGB12_1X12:
2601 input_seq = ISP_RGGB;
2602 break;
2603 default:
2604 input_seq = ISP_BGGR;
2605 break;
2606 }
2607 if (isp_device->use_isp) {
2608 vin_print("%s:isp%d reset!!!\n", __func__, isp_device->id);
2609 bsp_isp_set_para_ready(isp_device->id, PARA_NOT_READY);
2610 }
2611 #if defined CONFIG_D3D
2612 if (isp_device->use_isp && (isp_device->load_shadow[0x2d4 + 0x3]) & (1<<1)) {
2613 /* clear D3D rec_en 0x2d4 bit25*/
2614 isp_device->load_shadow[0x2d4 + 0x3] = (isp_device->load_shadow[0x2d4 + 0x3]) & (~(1<<1));
2615 memcpy(isp_device->isp_load.vir_addr, &isp_device->load_shadow[0], ISP_LOAD_DRAM_SIZE);
2616 }
2617 #endif
2618 /*****************stop*******************/
2619 #if defined CONFIG_ARCH_SUN8IW16P1
2620 if (csi_device->id == 0)
2621 cmb_rx_disable(csi_device->id);
2622 #endif
2623 csic_prs_disable(csi_device->id);
2624
2625 if (isp_device->use_isp) {
2626 csic_isp_bridge_disable(0);
2627
2628 bsp_isp_clr_irq_status(isp_device->id, ISP_IRQ_EN_ALL);
2629 bsp_isp_enable(isp_device->id, 0);
2630 bsp_isp_capture_stop(isp_device->id);
2631 }
2632 for (i = 0; i < VIN_MAX_DEV; i++) {
2633 if (vind->vinc[i] == NULL)
2634 continue;
2635 if (!vin_streaming(&vind->vinc[i]->vid_cap))
2636 continue;
2637
2638 if (vind->vinc[i]->csi_sel == csi_device->id) {
2639 vinc = vind->vinc[i];
2640
2641 vinc->vid_cap.frame_delay_cnt = 2;
2642 vipp_disable(vinc->vipp_sel);
2643 vipp_top_clk_en(vinc->vipp_sel, 0);
2644 csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_ALL);
2645 csic_dma_top_disable(vinc->vipp_sel);
2646 }
2647 }
2648
2649 /*****************start*******************/
2650 for (i = 0; i < VIN_MAX_DEV; i++) {
2651 if (vind->vinc[i] == NULL)
2652 continue;
2653 if (!vin_streaming(&vind->vinc[i]->vid_cap))
2654 continue;
2655
2656 if (vind->vinc[i]->csi_sel == csi_device->id) {
2657 vinc = vind->vinc[i];
2658
2659 csic_dma_top_enable(vinc->vipp_sel);
2660 vipp_top_clk_en(vinc->vipp_sel, 1);
2661 vipp_enable(vinc->vipp_sel);
2662 vinc->vin_status.frame_cnt = 0;
2663 vinc->vin_status.lost_cnt = 0;
2664 }
2665 }
2666 if (isp_device->use_isp) {
2667 bsp_isp_enable(isp_device->id, 1);
2668 bsp_isp_set_para_ready(isp_device->id, PARA_READY);
2669 bsp_isp_set_input_fmt(isp_device->id, input_seq);
2670 bsp_isp_capture_start(isp_device->id);
2671 isp_device->isp_frame_number = 0;
2672
2673 csic_isp_bridge_enable(0);
2674 }
2675
2676 csic_prs_enable(csi_device->id);
2677
2678 #if defined CONFIG_ARCH_SUN8IW16P1
2679 if (vinc->mipi_sel == 0)
2680 cmb_rx_enable(vinc->mipi_sel);
2681 #endif
2682
2683 csic_prs_capture_start(csi_device->id, 1, &mode);
2684
2685 isp_device->subdev.entity.stream_count = isp_stream_count;
2686 mutex_unlock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
2687 return ret;
2688 }
2689
vin_s_ctrl(struct v4l2_ctrl * ctrl)2690 static int vin_s_ctrl(struct v4l2_ctrl *ctrl)
2691 {
2692 struct vin_vid_cap *cap = container_of(ctrl->handler, struct vin_vid_cap, ctrl_handler);
2693 struct sensor_instance *inst = get_valid_sensor(cap->vinc);
2694 struct v4l2_subdev *sensor = cap->pipe.sd[VIN_IND_SENSOR];
2695 struct v4l2_subdev *flash = cap->pipe.sd[VIN_IND_FLASH];
2696 struct v4l2_subdev *act = cap->pipe.sd[VIN_IND_ACTUATOR];
2697 struct v4l2_subdev *isp = cap->pipe.sd[VIN_IND_ISP];
2698 struct actuator_ctrl_word_t vcm_ctrl;
2699 struct v4l2_control c;
2700 #ifndef CONFIG_ENABLE_SENSOR_FLIP_OPTION
2701 struct csic_dma_flip flip;
2702 #endif
2703 int ret = 0;
2704
2705 c.id = ctrl->id;
2706 c.value = ctrl->val;
2707
2708 switch (ctrl->id) {
2709 #ifdef CONFIG_ENABLE_SENSOR_FLIP_OPTION
2710 case V4L2_CID_VFLIP:
2711 if (!vin_streaming(cap)) {
2712 vin_err("cannot set sensor flip before stream on!\n");
2713 return -1;
2714 }
2715 cap->vinc->sensor_vflip = c.value;
2716 ret = sensor_flip_option(cap, c);
2717 return ret;
2718 case V4L2_CID_HFLIP:
2719 if (!vin_streaming(cap)) {
2720 vin_err("cannot set sensor flip before stream on!\n");
2721 return -1;
2722 }
2723 cap->vinc->sensor_hflip = c.value;
2724 ret = sensor_flip_option(cap, c);
2725 return ret;
2726 #else
2727 case V4L2_CID_VFLIP:
2728 if (cap->frame.fmt.fourcc == V4L2_PIX_FMT_LBC_2_0X ||
2729 cap->frame.fmt.fourcc == V4L2_PIX_FMT_LBC_2_5X ||
2730 cap->frame.fmt.fourcc == V4L2_PIX_FMT_LBC_1_0X) {
2731 vin_warn("when out fmt is LBC, FLIP is not support!\n");
2732 return -1;
2733 }
2734 cap->vinc->vflip = c.value;
2735 if (!vin_lpm(cap)) {
2736 flip.hflip_en = cap->vinc->hflip;
2737 flip.vflip_en = cap->vinc->vflip;
2738 csic_dma_flip_en(cap->vinc->vipp_sel, &flip);
2739 __osd_reg_setup(cap->vinc, &cap->osd);
2740 return 0;
2741 } else {
2742 vin_err("cannot set vflip before s_input, in low power mode!\n");
2743 return -1;
2744 }
2745 case V4L2_CID_HFLIP:
2746 if (cap->frame.fmt.fourcc == V4L2_PIX_FMT_LBC_2_0X ||
2747 cap->frame.fmt.fourcc == V4L2_PIX_FMT_LBC_2_5X ||
2748 cap->frame.fmt.fourcc == V4L2_PIX_FMT_LBC_1_0X) {
2749 vin_warn("when out fmt is LBC, FLIP is not support!\n");
2750 return -1;
2751 }
2752 cap->vinc->hflip = c.value;
2753 if (!vin_lpm(cap)) {
2754 flip.hflip_en = cap->vinc->hflip;
2755 flip.vflip_en = cap->vinc->vflip;
2756 csic_dma_flip_en(cap->vinc->vipp_sel, &flip);
2757 __osd_reg_setup(cap->vinc, &cap->osd);
2758 return 0;
2759 } else {
2760 vin_err("cannot set hflip before s_input, in low power mode!\n");
2761 return -1;
2762 }
2763 #endif
2764 default:
2765 break;
2766 }
2767
2768 /*
2769 * make sure g_ctrl will get the value that hardware is using
2770 * so that ctrl->flags should be V4L2_CTRL_FLAG_VOLATILE, after s_ctrl
2771 */
2772 switch (ctrl->id) {
2773 case V4L2_CID_EXPOSURE:
2774 case V4L2_CID_EXPOSURE_ABSOLUTE:
2775 case V4L2_CID_GAIN:
2776 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
2777 break;
2778 default:
2779 break;
2780 }
2781
2782 if (inst->is_isp_used && inst->is_bayer_raw) {
2783 switch (ctrl->id) {
2784 case V4L2_CID_BRIGHTNESS:
2785 case V4L2_CID_CONTRAST:
2786 case V4L2_CID_SATURATION:
2787 case V4L2_CID_HUE:
2788 case V4L2_CID_AUTO_WHITE_BALANCE:
2789 case V4L2_CID_EXPOSURE:
2790 case V4L2_CID_AUTOGAIN:
2791 case V4L2_CID_GAIN:
2792 case V4L2_CID_POWER_LINE_FREQUENCY:
2793 case V4L2_CID_HUE_AUTO:
2794 case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
2795 case V4L2_CID_SHARPNESS:
2796 case V4L2_CID_CHROMA_AGC:
2797 case V4L2_CID_COLORFX:
2798 case V4L2_CID_AUTOBRIGHTNESS:
2799 case V4L2_CID_BAND_STOP_FILTER:
2800 case V4L2_CID_ILLUMINATORS_1:
2801 case V4L2_CID_ILLUMINATORS_2:
2802 case V4L2_CID_EXPOSURE_AUTO:
2803 case V4L2_CID_EXPOSURE_ABSOLUTE:
2804 case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
2805 case V4L2_CID_FOCUS_ABSOLUTE:
2806 case V4L2_CID_FOCUS_RELATIVE:
2807 case V4L2_CID_FOCUS_AUTO:
2808 case V4L2_CID_AUTO_EXPOSURE_BIAS:
2809 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
2810 case V4L2_CID_WIDE_DYNAMIC_RANGE:
2811 case V4L2_CID_IMAGE_STABILIZATION:
2812 case V4L2_CID_ISO_SENSITIVITY:
2813 case V4L2_CID_ISO_SENSITIVITY_AUTO:
2814 case V4L2_CID_EXPOSURE_METERING:
2815 case V4L2_CID_SCENE_MODE:
2816 case V4L2_CID_3A_LOCK:
2817 case V4L2_CID_AUTO_FOCUS_START:
2818 case V4L2_CID_AUTO_FOCUS_STOP:
2819 case V4L2_CID_AUTO_FOCUS_RANGE:
2820 case V4L2_CID_AUTO_FOCUS_INIT:
2821 case V4L2_CID_AUTO_FOCUS_RELEASE:
2822 case V4L2_CID_GSENSOR_ROTATION:
2823 case V4L2_CID_TAKE_PICTURE:
2824 ret = v4l2_s_ctrl(NULL, isp->ctrl_handler, &c);
2825 break;
2826 case V4L2_CID_FLASH_LED_MODE:
2827 if (flash)
2828 ret = v4l2_s_ctrl(NULL, flash->ctrl_handler, &c);
2829 break;
2830 case V4L2_CID_FLASH_LED_MODE_V1:
2831 ret = v4l2_s_ctrl(NULL, isp->ctrl_handler, &c);
2832 if (flash)
2833 ret = v4l2_s_ctrl(NULL, flash->ctrl_handler, &c);
2834 break;
2835 default:
2836 ret = -EINVAL;
2837 break;
2838 }
2839 } else {
2840 switch (ctrl->id) {
2841 case V4L2_CID_FOCUS_ABSOLUTE:
2842 vcm_ctrl.code = ctrl->val;
2843 vcm_ctrl.sr = 0x0;
2844 ret = v4l2_subdev_call(act, core, ioctl, ACT_SET_CODE, &vcm_ctrl);
2845 break;
2846 case V4L2_CID_FLASH_LED_MODE:
2847 if (flash)
2848 ret = v4l2_s_ctrl(NULL, flash->ctrl_handler, &c);
2849 break;
2850 case V4L2_CID_AUTO_FOCUS_START:
2851 if (flash)
2852 sunxi_flash_check_to_start(flash, SW_CTRL_TORCH_ON);
2853 ret = v4l2_s_ctrl(NULL, sensor->ctrl_handler, &c);
2854 break;
2855 case V4L2_CID_AUTO_FOCUS_STOP:
2856 if (flash)
2857 sunxi_flash_stop(flash);
2858 ret = v4l2_s_ctrl(NULL, sensor->ctrl_handler, &c);
2859 break;
2860 case V4L2_CID_AE_WIN_X1:
2861 ret = __vin_sensor_set_ae_win(cap);
2862 break;
2863 case V4L2_CID_AF_WIN_X1:
2864 ret = __vin_sensor_set_af_win(cap);
2865 break;
2866 case V4L2_CID_AUTO_EXPOSURE_BIAS:
2867 c.value = ctrl->val;
2868 ret = v4l2_s_ctrl(NULL, sensor->ctrl_handler, &c);
2869 break;
2870 default:
2871 ret = v4l2_s_ctrl(NULL, sensor->ctrl_handler, &c);
2872 break;
2873 }
2874 }
2875 return ret;
2876 }
2877
2878 #ifdef CONFIG_COMPAT
vin_compat_ioctl32(struct file * file,unsigned int cmd,unsigned long arg)2879 static long vin_compat_ioctl32(struct file *file, unsigned int cmd,
2880 unsigned long arg)
2881 {
2882 void __user *up = compat_ptr(arg);
2883 long err = 0;
2884
2885 err = video_ioctl2(file, cmd, (unsigned long)up);
2886 return err;
2887 }
2888 #endif
2889 /* ------------------------------------------------------------------
2890 *File operations for the device
2891 *------------------------------------------------------------------*/
2892
2893 static const struct v4l2_ctrl_ops vin_ctrl_ops = {
2894 .g_volatile_ctrl = vin_g_volatile_ctrl,
2895 .s_ctrl = vin_s_ctrl,
2896 .try_ctrl = vin_try_ctrl,
2897 };
2898
2899 static const struct v4l2_file_operations vin_fops = {
2900 .owner = THIS_MODULE,
2901 .open = vin_open,
2902 .release = vin_close,
2903 .read = vb2_fop_read,
2904 .poll = vin_poll,
2905 .unlocked_ioctl = video_ioctl2,
2906 #ifdef CONFIG_COMPAT
2907 .compat_ioctl32 = vin_compat_ioctl32,
2908 #endif
2909 .mmap = vb2_fop_mmap,
2910 };
2911
2912 static const struct v4l2_ioctl_ops vin_ioctl_ops = {
2913 .vidioc_querycap = vidioc_querycap,
2914 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap_mplane,
2915 .vidioc_enum_framesizes = vidioc_enum_framesizes,
2916 .vidioc_g_fmt_vid_cap_mplane = vidioc_g_fmt_vid_cap_mplane,
2917 .vidioc_try_fmt_vid_cap_mplane = vidioc_try_fmt_vid_cap_mplane,
2918 .vidioc_s_fmt_vid_cap_mplane = vidioc_s_fmt_vid_cap_mplane,
2919 .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay,
2920 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
2921 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
2922 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
2923 .vidioc_overlay = vidioc_overlay,
2924 .vidioc_reqbufs = vb2_ioctl_reqbufs,
2925 .vidioc_querybuf = vb2_ioctl_querybuf,
2926 .vidioc_qbuf = vb2_ioctl_qbuf,
2927 .vidioc_dqbuf = vb2_ioctl_dqbuf,
2928 .vidioc_expbuf = vb2_ioctl_expbuf,
2929 .vidioc_enum_input = vidioc_enum_input,
2930 .vidioc_g_input = vidioc_g_input,
2931 .vidioc_s_input = vidioc_s_input,
2932 .vidioc_streamon = vidioc_streamon,
2933 .vidioc_streamoff = vidioc_streamoff,
2934 .vidioc_g_parm = vidioc_g_parm,
2935 .vidioc_s_parm = vidioc_s_parm,
2936 .vidioc_g_selection = vidioc_g_selection,
2937 .vidioc_s_selection = vidioc_s_selection,
2938 .vidioc_default = vin_param_handler,
2939 .vidioc_subscribe_event = vin_subscribe_event,
2940 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
2941 };
2942
2943 #if IS_ENABLED(CONFIG_VIDEO_SUNXI_VIN_SPECIAL)
vin_open_special(int id)2944 int vin_open_special(int id)
2945 {
2946 struct vin_core *vinc = vin_core_gbl[id];
2947 struct list_head *active = &vinc->vid_cap.vidq_active;
2948 struct list_head *done = &vinc->vid_cap.vidq_done;
2949
2950 INIT_LIST_HEAD(active);
2951 INIT_LIST_HEAD(done);
2952 vinc->vid_cap.special_active = 1;
2953
2954 if (vin_busy(&vinc->vid_cap)) {
2955 vin_err("device open busy\n");
2956 return -EBUSY;
2957 }
2958 set_bit(VIN_BUSY, &vinc->vid_cap.state);
2959 set_bit(VIN_LPM, &cap->state);
2960
2961 #if IS_ENABLED(CONFIG_DEVFREQ_DRAM_FREQ_WITH_SOFT_NOTIFY)
2962 dramfreq_master_access(MASTER_CSI, true);
2963 #endif
2964 return 0;
2965 }
2966 EXPORT_SYMBOL(vin_open_special);
2967
vin_s_input_special(int id,int i)2968 int vin_s_input_special(int id, int i)
2969 {
2970 struct vin_core *vinc = vin_core_gbl[id];
2971 struct vin_md *vind = dev_get_drvdata(vinc->v4l2_dev->dev);
2972 struct vin_vid_cap *cap = &vinc->vid_cap;
2973 struct modules_config *module = NULL;
2974 struct sensor_instance *inst = NULL;
2975 struct sensor_info *info = NULL;
2976
2977 int valid_idx = -1;
2978 int ret;
2979
2980 i = i > 1 ? 0 : i;
2981
2982 if (i == 0)
2983 vinc->sensor_sel = vinc->rear_sensor;
2984 else
2985 vinc->sensor_sel = vinc->front_sensor;
2986
2987 module = &vind->modules[vinc->sensor_sel];
2988 valid_idx = module->sensors.valid_idx;
2989
2990 if (valid_idx == NO_VALID_SENSOR) {
2991 vin_err("there is no valid sensor\n");
2992 return -EINVAL;
2993 }
2994
2995 if (__vin_sensor_setup_link(vinc, module, valid_idx, 1) < 0) {
2996 vin_err("sensor setup link failed\n");
2997 return -EINVAL;
2998 }
2999 if (__csi_isp_setup_link(vinc, 1) < 0) {
3000 vin_err("csi&isp setup link failed\n");
3001 return -EINVAL;
3002 }
3003 inst = &module->sensors.inst[valid_idx];
3004
3005 sunxi_isp_sensor_type(cap->pipe.sd[VIN_IND_ISP], inst->is_isp_used);
3006 vinc->support_raw = inst->is_isp_used;
3007
3008 ret = vin_pipeline_call(vinc, open, &cap->pipe, &cap->vdev.entity, true);
3009 if (ret < 0) {
3010 vin_err("vin pipeline open failed (%d)!\n", ret);
3011 return ret;
3012 }
3013
3014 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_ISP], core, init, 1);
3015 if (ret < 0) {
3016 vin_err("ISP init error at %s\n", __func__);
3017 return ret;
3018 }
3019
3020 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_SCALER], core, init, 1);
3021 if (ret < 0) {
3022 vin_err("SCALER init error at %s\n", __func__);
3023 return ret;
3024 }
3025
3026 /*save exp and gain for reopen, sensor init may reset gain to 0, so save before init!*/
3027 info = container_of(cap->pipe.sd[VIN_IND_SENSOR], struct sensor_info, sd);
3028 if (info) {
3029 vinc->exp_gain.exp_val = info->exp;
3030 vinc->exp_gain.gain_val = info->gain;
3031 vinc->stream_idx = info->stream_seq + 1;
3032 }
3033
3034 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], core, init, 1);
3035 if (ret) {
3036 vin_err("sensor initial error when selecting target device!\n");
3037 return ret;
3038 }
3039 clear_bit(VIN_LPM, &cap->state);
3040
3041 vinc->hflip = inst->hflip;
3042 vinc->vflip = inst->vflip;
3043
3044 return ret;
3045 }
3046 EXPORT_SYMBOL(vin_s_input_special);
3047
vin_close_special(int id)3048 int vin_close_special(int id)
3049 {
3050 struct vin_core *vinc = vin_core_gbl[id];
3051 struct vin_md *vind = dev_get_drvdata(vinc->v4l2_dev->dev);
3052 struct vin_vid_cap *cap = &vinc->vid_cap;
3053 struct list_head *active = &vinc->vid_cap.vidq_active;
3054 struct list_head *done = &vinc->vid_cap.vidq_done;
3055 struct modules_config *module = &vind->modules[vinc->sensor_sel];
3056 int valid_idx = module->sensors.valid_idx;
3057 int ret;
3058
3059 INIT_LIST_HEAD(active);
3060 INIT_LIST_HEAD(done);
3061 vinc->vid_cap.special_active = 0;
3062
3063 if (!vin_busy(cap)) {
3064 vin_warn("video%d device have been closed!\n", vinc->id);
3065 return 0;
3066 }
3067
3068 mutex_lock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
3069 if (!cap->pipe.sd[VIN_IND_SENSOR]->entity.use_count) {
3070 vin_err("%s is not used, video%d cannot be close!\n", cap->pipe.sd[VIN_IND_SENSOR]->name, vinc->id);
3071 mutex_unlock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
3072 return -1;
3073 }
3074
3075 if (vin_streaming(cap)) {
3076 clear_bit(VIN_STREAM, &cap->state);
3077 vin_pipeline_call(vinc, set_stream, &cap->pipe, 0);
3078 }
3079
3080 if (!vin_lpm(cap)) {
3081 set_bit(VIN_LPM, &cap->state);
3082 __csi_isp_setup_link(vinc, 0);
3083 __vin_sensor_setup_link(vinc, module, valid_idx, 0);
3084 }
3085
3086 ret = vin_pipeline_call(vinc, close, &cap->pipe);
3087 if (ret)
3088 vin_err("vin pipeline close failed!\n");
3089
3090 ret = v4l2_subdev_call(cap->pipe.sd[VIN_IND_ISP], core, init, 0);
3091
3092 /*software*/
3093 clear_bit(VIN_BUSY, &cap->state);
3094 mutex_unlock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
3095 #ifdef CONFIG_DEVFREQ_DRAM_FREQ_WITH_SOFT_NOTIFY
3096 dramfreq_master_access(MASTER_CSI, false);
3097 #endif
3098 vin_log(VIN_LOG_VIDEO, "video%d close\n", vinc->id);
3099 return 0;
3100 }
3101 EXPORT_SYMBOL(vin_close_special);
3102
vin_s_fmt_special(int id,struct v4l2_format * f)3103 int vin_s_fmt_special(int id, struct v4l2_format *f)
3104 {
3105 struct vin_core *vinc = vin_core_gbl[id];
3106
3107 return __vin_set_fmt(vinc, f);
3108 }
3109 EXPORT_SYMBOL(vin_s_fmt_special);
3110
vin_g_fmt_special(int id,struct v4l2_format * f)3111 int vin_g_fmt_special(int id, struct v4l2_format *f)
3112 {
3113 struct vin_core *vinc = vin_core_gbl[id];
3114
3115 f->fmt.pix.width = vinc->vid_cap.frame.width;
3116 f->fmt.pix.height = vinc->vid_cap.frame.height;
3117 f->fmt.pix.field = vinc->vid_cap.frame.fmt.field;
3118 f->fmt.pix.pixelformat = vinc->vid_cap.frame.fmt.mbus_code;
3119
3120 return 0;
3121 }
3122 EXPORT_SYMBOL(vin_g_fmt_special);
3123
vin_dqbuffer_special(int id,struct vin_buffer ** buf)3124 int vin_dqbuffer_special(int id, struct vin_buffer **buf)
3125 {
3126 struct vin_core *vinc = vin_core_gbl[id];
3127 struct list_head *done = &vinc->vid_cap.vidq_done;
3128 struct vin_vid_cap *cap = &vinc->vid_cap;
3129
3130 int ret = 0;
3131 unsigned long flags = 0;
3132
3133 spin_lock_irqsave(&cap->slock, flags);
3134 /* Release all active buffers */
3135 if (!list_empty(done)) {
3136 *buf = list_first_entry(done, struct vin_buffer, list);
3137 list_del(&((*buf)->list));
3138 (*buf)->state = VB2_BUF_STATE_DEQUEUED;
3139 } else {
3140 ret = -1;
3141 }
3142 spin_unlock_irqrestore(&cap->slock, flags);
3143
3144 return ret;
3145 }
3146 EXPORT_SYMBOL(vin_dqbuffer_special);
3147
vin_qbuffer_special(int id,struct vin_buffer * buf)3148 int vin_qbuffer_special(int id, struct vin_buffer *buf)
3149 {
3150 struct vin_core *vinc = vin_core_gbl[id];
3151 struct vin_vid_cap *cap = &vinc->vid_cap;
3152 unsigned long flags = 0;
3153 int ret = 0;
3154
3155 if (buf == NULL) {
3156 vin_err("buf is NULL, cannot qbuf\n");
3157 return -1;
3158 }
3159
3160 spin_lock_irqsave(&cap->slock, flags);
3161 list_add_tail(&buf->list, &cap->vidq_active);
3162 buf->state = VB2_BUF_STATE_QUEUED;
3163 spin_unlock_irqrestore(&cap->slock, flags);
3164
3165 return ret;
3166 }
3167 EXPORT_SYMBOL(vin_qbuffer_special);
3168
vin_streamon_special(int id,enum v4l2_buf_type i)3169 int vin_streamon_special(int id, enum v4l2_buf_type i)
3170 {
3171 struct vin_core *vinc = vin_core_gbl[id];
3172 struct vin_vid_cap *cap = &vinc->vid_cap;
3173 int ret = 0;
3174
3175 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
3176 ret = -EINVAL;
3177 goto streamon_error;
3178 }
3179
3180 if (vin_streaming(cap)) {
3181 vin_err("stream has been already on\n");
3182 ret = -1;
3183 goto streamon_error;
3184 }
3185
3186 #if 0
3187 schedule_work(&vinc->vid_cap.s_stream_task);
3188 #else
3189 mutex_lock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
3190 ret = vin_pipeline_call(cap->vinc, set_stream, &cap->pipe, cap->vinc->stream_idx);
3191 if (ret < 0)
3192 vin_err("video%d %s error!\n", vinc->id, __func__);
3193 set_bit(VIN_STREAM, &cap->state);
3194 /*set saved exp and gain for reopen, you can call the api in sensor_reg_init*/
3195 /*
3196 if (cap->vinc->exp_gain.exp_val && cap->vinc->exp_gain.gain_val) {
3197 v4l2_subdev_call(cap->pipe.sd[VIN_IND_SENSOR], core, ioctl,
3198 VIDIOC_VIN_SENSOR_EXP_GAIN, &cap->vinc->exp_gain);
3199 }
3200 */
3201 mutex_unlock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
3202 #endif
3203
3204 streamon_error:
3205 return ret;
3206 }
3207 EXPORT_SYMBOL(vin_streamon_special);
3208
vin_streamoff_special(int id,enum v4l2_buf_type i)3209 int vin_streamoff_special(int id, enum v4l2_buf_type i)
3210 {
3211 struct vin_core *vinc = vin_core_gbl[id];
3212 struct vin_md *vind = dev_get_drvdata(vinc->v4l2_dev->dev);
3213 struct vin_vid_cap *cap = &vinc->vid_cap;
3214 struct modules_config *module = &vind->modules[vinc->sensor_sel];
3215 int valid_idx = module->sensors.valid_idx;
3216 int ret = 0;
3217
3218 if (!vin_streaming(cap)) {
3219 vin_err("video%d has been already streaming off\n", vinc->id);
3220 goto streamoff_error;
3221 }
3222
3223 mutex_lock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
3224 clear_bit(VIN_STREAM, &cap->state);
3225 vin_pipeline_call(vinc, set_stream, &cap->pipe, 0);
3226 set_bit(VIN_LPM, &cap->state);
3227 __csi_isp_setup_link(vinc, 0);
3228 __vin_sensor_setup_link(vinc, module, valid_idx, 0);
3229 mutex_unlock(&cap->vdev.entity.graph_obj.mdev->graph_mutex);
3230
3231 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
3232 ret = -EINVAL;
3233 goto streamoff_error;
3234 }
3235
3236 streamoff_error:
3237 return ret;
3238 }
3239 EXPORT_SYMBOL(vin_streamoff_special);
3240
vin_register_buffer_done_callback(int id,void * func)3241 void vin_register_buffer_done_callback(int id, void *func)
3242 {
3243 struct vin_core *vinc = vin_core_gbl[id];
3244
3245 vinc->vid_cap.vin_buffer_process = func;
3246 }
3247 EXPORT_SYMBOL(vin_register_buffer_done_callback);
3248
vin_get_dev(int id)3249 struct device *vin_get_dev(int id)
3250 {
3251 struct vin_core *vinc = vin_core_gbl[id];
3252
3253 return get_device(&vinc->pdev->dev);
3254 }
3255 EXPORT_SYMBOL(vin_get_dev);
3256 #endif
3257
3258 static const struct v4l2_ctrl_config ae_win_ctrls[] = {
3259 {
3260 .ops = &vin_ctrl_ops,
3261 .id = V4L2_CID_AE_WIN_X1,
3262 .name = "R GAIN",
3263 .type = V4L2_CTRL_TYPE_INTEGER,
3264 .min = 32,
3265 .max = 3264,
3266 .step = 16,
3267 .def = 256,
3268 .flags = V4L2_CTRL_FLAG_VOLATILE,
3269 }, {
3270 .ops = &vin_ctrl_ops,
3271 .id = V4L2_CID_AE_WIN_Y1,
3272 .name = "R GAIN",
3273 .type = V4L2_CTRL_TYPE_INTEGER,
3274 .min = 32,
3275 .max = 3264,
3276 .step = 16,
3277 .def = 256,
3278 .flags = V4L2_CTRL_FLAG_VOLATILE,
3279 }, {
3280 .ops = &vin_ctrl_ops,
3281 .id = V4L2_CID_AE_WIN_X2,
3282 .name = "R GAIN",
3283 .type = V4L2_CTRL_TYPE_INTEGER,
3284 .min = 32,
3285 .max = 3264,
3286 .step = 16,
3287 .def = 256,
3288 .flags = V4L2_CTRL_FLAG_VOLATILE,
3289 }, {
3290 .ops = &vin_ctrl_ops,
3291 .id = V4L2_CID_AE_WIN_Y2,
3292 .name = "R GAIN",
3293 .type = V4L2_CTRL_TYPE_INTEGER,
3294 .min = 32,
3295 .max = 3264,
3296 .step = 16,
3297 .def = 256,
3298 .flags = V4L2_CTRL_FLAG_VOLATILE,
3299 }
3300 };
3301
3302 static const struct v4l2_ctrl_config af_win_ctrls[] = {
3303 {
3304 .ops = &vin_ctrl_ops,
3305 .id = V4L2_CID_AF_WIN_X1,
3306 .name = "R GAIN",
3307 .type = V4L2_CTRL_TYPE_INTEGER,
3308 .min = 32,
3309 .max = 3264,
3310 .step = 16,
3311 .def = 256,
3312 .flags = V4L2_CTRL_FLAG_VOLATILE,
3313 }, {
3314 .ops = &vin_ctrl_ops,
3315 .id = V4L2_CID_AF_WIN_Y1,
3316 .name = "R GAIN",
3317 .type = V4L2_CTRL_TYPE_INTEGER,
3318 .min = 32,
3319 .max = 3264,
3320 .step = 16,
3321 .def = 256,
3322 .flags = V4L2_CTRL_FLAG_VOLATILE,
3323 }, {
3324 .ops = &vin_ctrl_ops,
3325 .id = V4L2_CID_AF_WIN_X2,
3326 .name = "R GAIN",
3327 .type = V4L2_CTRL_TYPE_INTEGER,
3328 .min = 32,
3329 .max = 3264,
3330 .step = 16,
3331 .def = 256,
3332 .flags = V4L2_CTRL_FLAG_VOLATILE,
3333 }, {
3334 .ops = &vin_ctrl_ops,
3335 .id = V4L2_CID_AF_WIN_Y2,
3336 .name = "R GAIN",
3337 .type = V4L2_CTRL_TYPE_INTEGER,
3338 .min = 32,
3339 .max = 3264,
3340 .step = 16,
3341 .def = 256,
3342 .flags = V4L2_CTRL_FLAG_VOLATILE,
3343 }
3344 };
3345
3346 static const struct v4l2_ctrl_config custom_ctrls[] = {
3347 {
3348 .ops = &vin_ctrl_ops,
3349 .id = V4L2_CID_HOR_VISUAL_ANGLE,
3350 .name = "Horizontal Visual Angle",
3351 .type = V4L2_CTRL_TYPE_INTEGER,
3352 .min = 0,
3353 .max = 360,
3354 .step = 1,
3355 .def = 60,
3356 .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
3357 }, {
3358 .ops = &vin_ctrl_ops,
3359 .id = V4L2_CID_VER_VISUAL_ANGLE,
3360 .name = "Vertical Visual Angle",
3361 .type = V4L2_CTRL_TYPE_INTEGER,
3362 .min = 0,
3363 .max = 360,
3364 .step = 1,
3365 .def = 60,
3366 .flags = V4L2_CTRL_FLAG_VOLATILE | V4L2_CTRL_FLAG_READ_ONLY,
3367 }, {
3368 .ops = &vin_ctrl_ops,
3369 .id = V4L2_CID_FOCUS_LENGTH,
3370 .name = "Focus Length",
3371 .type = V4L2_CTRL_TYPE_INTEGER,
3372 .min = 0,
3373 .max = 1000,
3374 .step = 1,
3375 .def = 280,
3376 .flags = V4L2_CTRL_FLAG_VOLATILE,
3377 }, {
3378 .ops = &vin_ctrl_ops,
3379 .id = V4L2_CID_AUTO_FOCUS_INIT,
3380 .name = "AutoFocus Initial",
3381 .type = V4L2_CTRL_TYPE_BUTTON,
3382 .min = 0,
3383 .max = 0,
3384 .step = 0,
3385 .def = 0,
3386 }, {
3387 .ops = &vin_ctrl_ops,
3388 .id = V4L2_CID_AUTO_FOCUS_RELEASE,
3389 .name = "AutoFocus Release",
3390 .type = V4L2_CTRL_TYPE_BUTTON,
3391 .min = 0,
3392 .max = 0,
3393 .step = 0,
3394 .def = 0,
3395 }, {
3396 .ops = &vin_ctrl_ops,
3397 .id = V4L2_CID_GSENSOR_ROTATION,
3398 .name = "Gsensor Rotaion",
3399 .type = V4L2_CTRL_TYPE_INTEGER,
3400 .min = -180,
3401 .max = 180,
3402 .step = 90,
3403 .def = 0,
3404 }, {
3405 .ops = &vin_ctrl_ops,
3406 .id = V4L2_CID_TAKE_PICTURE,
3407 .name = "Take Picture",
3408 .type = V4L2_CTRL_TYPE_INTEGER,
3409 .min = 0,
3410 .max = 16,
3411 .step = 1,
3412 .def = 0,
3413 }, {
3414 .ops = &vin_ctrl_ops,
3415 .id = V4L2_CID_SENSOR_TYPE,
3416 .name = "Sensor type",
3417 .type = V4L2_CTRL_TYPE_MENU,
3418 .min = 0,
3419 .max = 1,
3420 .def = 0,
3421 .menu_skip_mask = 0x0,
3422 .qmenu = sensor_info_type,
3423 .flags = V4L2_CTRL_FLAG_VOLATILE,
3424 }, {
3425 .ops = &vin_ctrl_ops,
3426 .id = V4L2_CID_FLASH_LED_MODE_V1,
3427 .name = "VIN Flash ctrl",
3428 .type = V4L2_CTRL_TYPE_MENU,
3429 .min = 0,
3430 .max = 2,
3431 .def = 0,
3432 .menu_skip_mask = 0x0,
3433 .qmenu = flash_led_mode_v1,
3434 .flags = 0,
3435 .step = 0,
3436 },
3437 };
3438 static const s64 iso_qmenu[] = {
3439 100, 200, 400, 800, 1600, 3200, 6400,
3440 };
3441 static const s64 exp_bias_qmenu[] = {
3442 -4, -3, -2, -1, 0, 1, 2, 3, 4,
3443 };
3444
vin_init_controls(struct v4l2_ctrl_handler * hdl,struct vin_vid_cap * cap)3445 int vin_init_controls(struct v4l2_ctrl_handler *hdl, struct vin_vid_cap *cap)
3446 {
3447 struct v4l2_ctrl *ctrl;
3448 unsigned int i, ret = 0;
3449
3450 v4l2_ctrl_handler_init(hdl, 40 + ARRAY_SIZE(custom_ctrls)
3451 + ARRAY_SIZE(ae_win_ctrls) + ARRAY_SIZE(af_win_ctrls));
3452 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_BRIGHTNESS, -128, 128, 1, 0);
3453 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_CONTRAST, -128, 128, 1, 0);
3454 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_SATURATION, -256, 512, 1, 0);
3455 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_HUE, -180, 180, 1, 0);
3456 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
3457 ctrl = v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_EXPOSURE, 1, 65536 * 16, 1, 1);
3458 if (ctrl != NULL)
3459 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
3460 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
3461 ctrl = v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_GAIN, 16, 6000 * 16, 1, 16);
3462 if (ctrl != NULL)
3463 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
3464 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
3465 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
3466
3467 v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops,
3468 V4L2_CID_POWER_LINE_FREQUENCY,
3469 V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
3470 V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
3471 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_HUE_AUTO, 0, 1, 1, 1);
3472 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops,
3473 V4L2_CID_WHITE_BALANCE_TEMPERATURE, 2800, 10000, 1, 6500);
3474 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_SHARPNESS, 0, 1000, 1, 0);
3475 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_CHROMA_AGC, 0, 1, 1, 1);
3476 v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops, V4L2_CID_COLORFX,
3477 V4L2_COLORFX_SET_CBCR, 0, V4L2_COLORFX_NONE);
3478 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTOBRIGHTNESS, 0, 1, 1, 1);
3479 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_BAND_STOP_FILTER, 0, 1, 1, 1);
3480 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_ILLUMINATORS_1, 0, 1, 1, 0);
3481 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_ILLUMINATORS_2, 0, 1, 1, 0);
3482 v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
3483 V4L2_EXPOSURE_APERTURE_PRIORITY, 0,
3484 V4L2_EXPOSURE_AUTO);
3485 ctrl = v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_EXPOSURE_ABSOLUTE, 1, 30 * 1000000, 1, 1);
3486 if (ctrl != NULL)
3487 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
3488 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_EXPOSURE_AUTO_PRIORITY, 0, 1, 1, 0);
3489 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_FOCUS_ABSOLUTE, 0, 127, 1, 0);
3490 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_FOCUS_RELATIVE, -127, 127, 1, 0);
3491 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_FOCUS_AUTO, 0, 1, 1, 1);
3492 v4l2_ctrl_new_int_menu(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_EXPOSURE_BIAS,
3493 ARRAY_SIZE(exp_bias_qmenu) - 1,
3494 ARRAY_SIZE(exp_bias_qmenu) / 2, exp_bias_qmenu);
3495 v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops,
3496 V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
3497 V4L2_WHITE_BALANCE_SHADE, 0,
3498 V4L2_WHITE_BALANCE_AUTO);
3499 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_WIDE_DYNAMIC_RANGE, 0, 1, 1, 0);
3500 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_IMAGE_STABILIZATION, 0, 1, 1, 0);
3501 v4l2_ctrl_new_int_menu(hdl, &vin_ctrl_ops, V4L2_CID_ISO_SENSITIVITY,
3502 ARRAY_SIZE(iso_qmenu) - 1,
3503 ARRAY_SIZE(iso_qmenu) / 2 - 1, iso_qmenu);
3504 v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops,
3505 V4L2_CID_ISO_SENSITIVITY_AUTO,
3506 V4L2_ISO_SENSITIVITY_AUTO, 0,
3507 V4L2_ISO_SENSITIVITY_AUTO);
3508 v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops,
3509 V4L2_CID_EXPOSURE_METERING,
3510 V4L2_EXPOSURE_METERING_MATRIX, 0,
3511 V4L2_EXPOSURE_METERING_AVERAGE);
3512 v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops, V4L2_CID_SCENE_MODE,
3513 V4L2_SCENE_MODE_TEXT, 0, V4L2_SCENE_MODE_NONE);
3514 ctrl = v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_3A_LOCK, 0, 7, 0, 0);
3515 if (ctrl != NULL)
3516 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
3517 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_FOCUS_START, 0, 0, 0, 0);
3518 v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_FOCUS_STOP, 0, 0, 0, 0);
3519 ctrl = v4l2_ctrl_new_std(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_FOCUS_STATUS, 0, 7, 0, 0);
3520 if (ctrl != NULL)
3521 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
3522 v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops, V4L2_CID_AUTO_FOCUS_RANGE,
3523 V4L2_AUTO_FOCUS_RANGE_INFINITY, 0,
3524 V4L2_AUTO_FOCUS_RANGE_AUTO);
3525 v4l2_ctrl_new_std_menu(hdl, &vin_ctrl_ops, V4L2_CID_FLASH_LED_MODE,
3526 V4L2_FLASH_LED_MODE_RED_EYE, 0,
3527 V4L2_FLASH_LED_MODE_NONE);
3528
3529 for (i = 0; i < ARRAY_SIZE(custom_ctrls); i++)
3530 v4l2_ctrl_new_custom(hdl, &custom_ctrls[i], NULL);
3531
3532 for (i = 0; i < ARRAY_SIZE(ae_win_ctrls); i++)
3533 cap->ae_win[i] = v4l2_ctrl_new_custom(hdl,
3534 &ae_win_ctrls[i], NULL);
3535 v4l2_ctrl_cluster(ARRAY_SIZE(ae_win_ctrls), &cap->ae_win[0]);
3536
3537 for (i = 0; i < ARRAY_SIZE(af_win_ctrls); i++)
3538 cap->af_win[i] = v4l2_ctrl_new_custom(hdl,
3539 &af_win_ctrls[i], NULL);
3540 v4l2_ctrl_cluster(ARRAY_SIZE(af_win_ctrls), &cap->af_win[0]);
3541
3542 if (hdl->error) {
3543 ret = hdl->error;
3544 v4l2_ctrl_handler_free(hdl);
3545 }
3546 return ret;
3547 }
3548
vin_init_video(struct v4l2_device * v4l2_dev,struct vin_vid_cap * cap)3549 int vin_init_video(struct v4l2_device *v4l2_dev, struct vin_vid_cap *cap)
3550 {
3551 int ret = 0;
3552 struct vb2_queue *q;
3553 static u64 vin_dma_mask = DMA_BIT_MASK(32);
3554
3555 snprintf(cap->vdev.name, sizeof(cap->vdev.name),
3556 "vin_video%d", cap->vinc->id);
3557 cap->vdev.fops = &vin_fops;
3558 cap->vdev.ioctl_ops = &vin_ioctl_ops;
3559 cap->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE_MPLANE |
3560 V4L2_CAP_STREAMING | V4L2_CAP_READWRITE;
3561 cap->vdev.release = video_device_release_empty;
3562 cap->vdev.ctrl_handler = &cap->ctrl_handler;
3563 cap->vdev.v4l2_dev = v4l2_dev;
3564 cap->vdev.queue = &cap->vb_vidq;
3565 cap->vdev.lock = &cap->lock;
3566 cap->vdev.flags = V4L2_FL_USES_V4L2_FH;
3567 ret = video_register_device(&cap->vdev, VFL_TYPE_VIDEO, cap->vinc->id);
3568 if (ret < 0) {
3569 vin_err("Error video_register_device!!\n");
3570 return -1;
3571 }
3572 video_set_drvdata(&cap->vdev, cap->vinc);
3573 vin_log(VIN_LOG_VIDEO, "V4L2 device registered as %s\n",
3574 video_device_node_name(&cap->vdev));
3575
3576 /* Initialize videobuf2 queue as per the buffer type */
3577 cap->vinc->pdev->dev.dma_mask = &vin_dma_mask;
3578 cap->vinc->pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
3579 cap->dev = &cap->vinc->pdev->dev;
3580 if (!cap->dev->dma_parms) {
3581 ret = vb2_dma_contig_set_max_seg_size(&cap->vinc->pdev->dev, DMA_BIT_MASK(32));
3582 if (ret < 0 || IS_ERR_OR_NULL(cap->dev->dma_parms)) {
3583 vin_err("Failed to get the context\n");
3584 return -1;
3585 }
3586 cap->dma_parms_alloc = true;
3587 }
3588 /* initialize queue */
3589 q = &cap->vb_vidq;
3590 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
3591 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
3592 q->drv_priv = cap;
3593 q->buf_struct_size = sizeof(struct vin_buffer);
3594 q->ops = &vin_video_qops;
3595 q->mem_ops = &vb2_dma_contig_memops;
3596 q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
3597 q->lock = &cap->lock;
3598
3599 ret = vb2_queue_init(q);
3600 if (ret) {
3601 vin_err("vb2_queue_init() failed\n");
3602 if (cap->dma_parms_alloc)
3603 vb2_dma_contig_clear_max_seg_size(cap->dev);
3604 return ret;
3605 }
3606
3607 cap->vd_pad.flags = MEDIA_PAD_FL_SINK;
3608 ret = media_entity_pads_init(&cap->vdev.entity, 1, &cap->vd_pad);
3609 if (ret)
3610 return ret;
3611
3612 INIT_WORK(&cap->s_stream_task, __vin_s_stream_handle);
3613
3614 cap->state = 0;
3615 cap->registered = 1;
3616 /* initial state */
3617 cap->capture_mode = V4L2_MODE_PREVIEW;
3618 /* init video dma queues */
3619 INIT_LIST_HEAD(&cap->vidq_active);
3620 mutex_init(&cap->lock);
3621 spin_lock_init(&cap->slock);
3622
3623 return 0;
3624 }
3625
vin_link_setup(struct media_entity * entity,const struct media_pad * local,const struct media_pad * remote,u32 flags)3626 static int vin_link_setup(struct media_entity *entity,
3627 const struct media_pad *local,
3628 const struct media_pad *remote, u32 flags)
3629 {
3630 return 0;
3631 }
3632
3633 static const struct media_entity_operations vin_sd_media_ops = {
3634 .link_setup = vin_link_setup,
3635 };
3636
vin_video_core_s_power(struct v4l2_subdev * sd,int on)3637 static int vin_video_core_s_power(struct v4l2_subdev *sd, int on)
3638 {
3639 struct vin_core *vinc = v4l2_get_subdevdata(sd);
3640
3641 if (on) {
3642 pm_runtime_get_sync(&vinc->pdev->dev);/* call pm_runtime resume */
3643 } else {
3644 pm_runtime_put_sync(&vinc->pdev->dev);/* call pm_runtime suspend */
3645 }
3646 return 0;
3647 }
3648
vin_subdev_s_stream(struct v4l2_subdev * sd,int enable)3649 static int vin_subdev_s_stream(struct v4l2_subdev *sd, int enable)
3650 {
3651 struct vin_core *vinc = v4l2_get_subdevdata(sd);
3652 struct vin_vid_cap *cap = &vinc->vid_cap;
3653 struct csic_dma_cfg cfg;
3654 struct csic_dma_flip flip;
3655 struct dma_output_size size;
3656 struct dma_buf_len buf_len;
3657 struct dma_flip_size flip_size;
3658 int flag = 0;
3659 int flip_mul = 2;
3660
3661 if (enable) {
3662 memset(&cfg, 0, sizeof(cfg));
3663 memset(&size, 0, sizeof(size));
3664 memset(&buf_len, 0, sizeof(buf_len));
3665
3666 switch (cap->frame.fmt.field) {
3667 case V4L2_FIELD_ANY:
3668 case V4L2_FIELD_NONE:
3669 cfg.field = FIELD_EITHER;
3670 break;
3671 case V4L2_FIELD_TOP:
3672 cfg.field = FIELD_1;
3673 flag = 1;
3674 break;
3675 case V4L2_FIELD_BOTTOM:
3676 cfg.field = FIELD_2;
3677 flag = 1;
3678 break;
3679 case V4L2_FIELD_INTERLACED:
3680 cfg.field = FIELD_EITHER;
3681 flag = 1;
3682 break;
3683 default:
3684 cfg.field = FIELD_EITHER;
3685 break;
3686 }
3687
3688 switch (cap->frame.fmt.fourcc) {
3689 case V4L2_PIX_FMT_NV12:
3690 case V4L2_PIX_FMT_NV12M:
3691 case V4L2_PIX_FMT_FBC:
3692 cfg.fmt = flag ? FRAME_UV_CB_YUV420 : FIELD_UV_CB_YUV420;
3693 buf_len.buf_len_y = cap->frame.o_width;
3694 buf_len.buf_len_c = buf_len.buf_len_y;
3695 break;
3696 case V4L2_PIX_FMT_LBC_2_0X:
3697 case V4L2_PIX_FMT_LBC_2_5X:
3698 case V4L2_PIX_FMT_LBC_1_0X:
3699 cfg.fmt = LBC_MODE_OUTPUT;
3700 buf_len.buf_len_y = cap->lbc_cmp.line_tar_bits[1] >> 3;
3701 buf_len.buf_len_c = cap->lbc_cmp.line_tar_bits[0] >> 3;
3702 break;
3703 case V4L2_PIX_FMT_NV21:
3704 case V4L2_PIX_FMT_NV21M:
3705 cfg.fmt = flag ? FRAME_VU_CB_YUV420 : FIELD_VU_CB_YUV420;
3706 buf_len.buf_len_y = cap->frame.o_width;
3707 buf_len.buf_len_c = buf_len.buf_len_y;
3708 break;
3709 case V4L2_PIX_FMT_YVU420:
3710 case V4L2_PIX_FMT_YUV420:
3711 case V4L2_PIX_FMT_YUV420M:
3712 cfg.fmt = flag ? FRAME_PLANAR_YUV420 : FIELD_PLANAR_YUV420;
3713 buf_len.buf_len_y = cap->frame.o_width;
3714 buf_len.buf_len_c = buf_len.buf_len_y >> 1;
3715 break;
3716 case V4L2_PIX_FMT_GREY:
3717 cfg.fmt = flag ? FRAME_CB_YUV400 : FIELD_CB_YUV400;
3718 buf_len.buf_len_y = cap->frame.o_width;
3719 break;
3720 case V4L2_PIX_FMT_YUV422P:
3721 cfg.fmt = flag ? FRAME_PLANAR_YUV422 : FIELD_PLANAR_YUV422;
3722 buf_len.buf_len_y = cap->frame.o_width;
3723 buf_len.buf_len_c = buf_len.buf_len_y >> 1;
3724 break;
3725 case V4L2_PIX_FMT_NV61:
3726 case V4L2_PIX_FMT_NV61M:
3727 cfg.fmt = flag ? FRAME_VU_CB_YUV422 : FIELD_VU_CB_YUV422;
3728 buf_len.buf_len_y = cap->frame.o_width;
3729 buf_len.buf_len_c = buf_len.buf_len_y;
3730 break;
3731 case V4L2_PIX_FMT_NV16:
3732 case V4L2_PIX_FMT_NV16M:
3733 cfg.fmt = flag ? FRAME_UV_CB_YUV422 : FIELD_UV_CB_YUV422;
3734 buf_len.buf_len_y = cap->frame.o_width;
3735 buf_len.buf_len_c = buf_len.buf_len_y;
3736 break;
3737 case V4L2_PIX_FMT_SBGGR8:
3738 case V4L2_PIX_FMT_SGBRG8:
3739 case V4L2_PIX_FMT_SGRBG8:
3740 case V4L2_PIX_FMT_SRGGB8:
3741 flip_mul = 1;
3742 cfg.fmt = flag ? FRAME_RAW_8 : FIELD_RAW_8;
3743 buf_len.buf_len_y = cap->frame.o_width;
3744 buf_len.buf_len_c = buf_len.buf_len_y;
3745 break;
3746 case V4L2_PIX_FMT_SBGGR10:
3747 case V4L2_PIX_FMT_SGBRG10:
3748 case V4L2_PIX_FMT_SGRBG10:
3749 case V4L2_PIX_FMT_SRGGB10:
3750 flip_mul = 1;
3751 cfg.fmt = flag ? FRAME_RAW_10 : FIELD_RAW_10;
3752 buf_len.buf_len_y = cap->frame.o_width * 2;
3753 buf_len.buf_len_c = buf_len.buf_len_y;
3754 break;
3755 case V4L2_PIX_FMT_SBGGR12:
3756 case V4L2_PIX_FMT_SGBRG12:
3757 case V4L2_PIX_FMT_SGRBG12:
3758 case V4L2_PIX_FMT_SRGGB12:
3759 flip_mul = 1;
3760 cfg.fmt = flag ? FRAME_RAW_12 : FIELD_RAW_12;
3761 buf_len.buf_len_y = cap->frame.o_width * 2;
3762 buf_len.buf_len_c = buf_len.buf_len_y;
3763 break;
3764 default:
3765 cfg.fmt = flag ? FRAME_UV_CB_YUV420 : FIELD_UV_CB_YUV420;
3766 buf_len.buf_len_y = cap->frame.o_width;
3767 buf_len.buf_len_c = buf_len.buf_len_y;
3768 break;
3769 }
3770
3771 if (vinc->isp_dbg.debug_en) {
3772 buf_len.buf_len_y = 0;
3773 buf_len.buf_len_c = 0;
3774 }
3775
3776 cfg.ds = vinc->fps_ds;
3777
3778 csic_dma_config(vinc->vipp_sel, &cfg);
3779 size.hor_len = vinc->isp_dbg.debug_en ? 0 : cap->frame.o_width;
3780 size.ver_len = vinc->isp_dbg.debug_en ? 0 : cap->frame.o_height;
3781 size.hor_start = vinc->isp_dbg.debug_en ? 0 : cap->frame.offs_h;
3782 size.ver_start = vinc->isp_dbg.debug_en ? 0 : cap->frame.offs_v;
3783 flip_size.hor_len = vinc->isp_dbg.debug_en ? 0 : cap->frame.o_width * flip_mul;
3784 flip_size.ver_len = vinc->isp_dbg.debug_en ? 0 : cap->frame.o_height;
3785 flip.hflip_en = vinc->hflip;
3786 flip.vflip_en = vinc->vflip;
3787
3788 if (vinc->large_image == 2) {
3789 size.hor_len /= 2;
3790 flip_size.hor_len /= 2;
3791 }
3792
3793 csic_dma_output_size_cfg(vinc->vipp_sel, &size);
3794 /* csic_dma_10bit_cut2_8bit_enable(vinc->vipp_sel); */
3795
3796 switch (cap->frame.fmt.fourcc) {
3797 case V4L2_PIX_FMT_FBC:
3798 csic_dma_buf_length_software_enable(vinc->vipp_sel, 0);
3799 csi_dam_flip_software_enable(vinc->vipp_sel, 0);
3800 csic_dma_flip_en(vinc->vipp_sel, &flip);
3801 csic_fbc_enable(vinc->vipp_sel);
3802 break;
3803 case V4L2_PIX_FMT_LBC_2_0X:
3804 case V4L2_PIX_FMT_LBC_2_5X:
3805 case V4L2_PIX_FMT_LBC_1_0X:
3806 csi_dam_flip_software_enable(vinc->vipp_sel, 1);
3807 #if defined CONFIG_ARCH_SUN8IW16P1
3808 csic_dma_buf_length_software_enable(vinc->vipp_sel, 1);
3809 #else
3810 csic_dma_buf_length_software_enable(vinc->vipp_sel, 0);
3811 #endif
3812 csic_lbc_enable(vinc->vipp_sel);
3813 csic_lbc_cmp_ratio(vinc->vipp_sel, &cap->lbc_cmp);
3814 break;
3815 default:
3816 csic_dma_buf_length_software_enable(vinc->vipp_sel, 0);
3817 csi_dam_flip_software_enable(vinc->vipp_sel, 0);
3818 csic_dma_flip_en(vinc->vipp_sel, &flip);
3819 csic_dma_enable(vinc->vipp_sel);
3820 break;
3821 }
3822
3823 csic_dma_buffer_length(vinc->vipp_sel, &buf_len);
3824 csic_dma_flip_size(vinc->vipp_sel, &flip_size);
3825
3826 /* give up line_cnt interrupt. process in vsync and frame_done isr.*/
3827 /*csic_dma_line_cnt(vinc->vipp_sel, cap->frame.o_height / 16 * 12);*/
3828 csic_frame_cnt_enable(vinc->vipp_sel);
3829
3830 #ifndef BUF_AUTO_UPDATE
3831 vin_set_next_buf_addr(vinc);
3832 csic_dma_top_enable(vinc->vipp_sel);
3833
3834 csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_ALL);
3835
3836 csic_dma_int_enable(vinc->vipp_sel, DMA_INT_BUF_0_OVERFLOW | DMA_INT_BUF_1_OVERFLOW |
3837 DMA_INT_BUF_2_OVERFLOW | DMA_INT_HBLANK_OVERFLOW | DMA_INT_VSYNC_TRIG |
3838 DMA_INT_CAPTURE_DONE | DMA_INT_FRAME_DONE | DMA_INT_LBC_HB);
3839 #else
3840 csic_dma_top_enable(vinc->vipp_sel);
3841 vin_set_next_buf_addr(vinc);
3842
3843 csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_ALL);
3844
3845 csic_dma_int_enable(vinc->vipp_sel, DMA_INT_BUF_0_OVERFLOW | DMA_INT_BUF_1_OVERFLOW |
3846 DMA_INT_BUF_2_OVERFLOW | DMA_INT_HBLANK_OVERFLOW | DMA_INT_VSYNC_TRIG |
3847 DMA_INT_CAPTURE_DONE | DMA_INT_STORED_FRM_CNT | DMA_INT_FRM_LOST | DMA_INT_LBC_HB);
3848 #endif
3849 } else {
3850 csic_dma_top_disable(vinc->vipp_sel);
3851 csic_dma_int_disable(vinc->vipp_sel, DMA_INT_ALL);
3852 csic_dma_int_clear_status(vinc->vipp_sel, DMA_INT_ALL);
3853 switch (cap->frame.fmt.fourcc) {
3854 case V4L2_PIX_FMT_FBC:
3855 csic_fbc_disable(vinc->vipp_sel);
3856 break;
3857 case V4L2_PIX_FMT_LBC_2_0X:
3858 case V4L2_PIX_FMT_LBC_2_5X:
3859 case V4L2_PIX_FMT_LBC_1_0X:
3860 csic_lbc_disable(vinc->vipp_sel);
3861 break;
3862 default:
3863 csic_dma_disable(vinc->vipp_sel);
3864 break;
3865 }
3866 }
3867
3868 vin_log(VIN_LOG_FMT, "csic_dma%d %s, %d*%d hoff: %d voff: %d\n",
3869 vinc->id, enable ? "stream on" : "stream off",
3870 cap->frame.o_width, cap->frame.o_height,
3871 cap->frame.offs_h, cap->frame.offs_v);
3872
3873 return 0;
3874 }
3875
3876 static struct v4l2_subdev_core_ops vin_subdev_core_ops = {
3877 .s_power = vin_video_core_s_power,
3878 };
3879
3880 static const struct v4l2_subdev_video_ops vin_subdev_video_ops = {
3881 .s_stream = vin_subdev_s_stream,
3882 };
3883
3884 static struct v4l2_subdev_ops vin_subdev_ops = {
3885 .core = &vin_subdev_core_ops,
3886 .video = &vin_subdev_video_ops,
3887 };
3888
vin_capture_subdev_registered(struct v4l2_subdev * sd)3889 static int vin_capture_subdev_registered(struct v4l2_subdev *sd)
3890 {
3891 struct vin_core *vinc = v4l2_get_subdevdata(sd);
3892 int ret;
3893
3894 vinc->vid_cap.vinc = vinc;
3895 if (vin_init_controls(&vinc->vid_cap.ctrl_handler, &vinc->vid_cap)) {
3896 vin_err("Error v4l2 ctrls new!!\n");
3897 return -1;
3898 }
3899
3900 vinc->pipeline_ops = v4l2_get_subdev_hostdata(sd);
3901 if (vin_init_video(sd->v4l2_dev, &vinc->vid_cap)) {
3902 vin_err("vin init video!!!!\n");
3903 vinc->pipeline_ops = NULL;
3904 }
3905 ret = sysfs_create_link(&vinc->vid_cap.vdev.dev.kobj,
3906 &vinc->pdev->dev.kobj, "vin_dbg");
3907 if (ret)
3908 vin_err("sysfs_create_link failed\n");
3909
3910 return 0;
3911 }
3912
vin_capture_subdev_unregistered(struct v4l2_subdev * sd)3913 static void vin_capture_subdev_unregistered(struct v4l2_subdev *sd)
3914 {
3915 struct vin_core *vinc = v4l2_get_subdevdata(sd);
3916
3917 if (vinc == NULL)
3918 return;
3919
3920 if (video_is_registered(&vinc->vid_cap.vdev)) {
3921 sysfs_remove_link(&vinc->vid_cap.vdev.dev.kobj, "vin_dbg");
3922 vin_log(VIN_LOG_VIDEO, "unregistering %s\n",
3923 video_device_node_name(&vinc->vid_cap.vdev));
3924 media_entity_cleanup(&vinc->vid_cap.vdev.entity);
3925 if (vinc->vid_cap.dma_parms_alloc && !IS_ERR_OR_NULL(vinc->vid_cap.dev->dma_parms))
3926 vb2_dma_contig_clear_max_seg_size(vinc->vid_cap.dev);
3927 video_unregister_device(&vinc->vid_cap.vdev);
3928 mutex_destroy(&vinc->vid_cap.lock);
3929 }
3930 v4l2_ctrl_handler_free(&vinc->vid_cap.ctrl_handler);
3931 vinc->pipeline_ops = NULL;
3932 }
3933
3934 static const struct v4l2_subdev_internal_ops vin_capture_sd_internal_ops = {
3935 .registered = vin_capture_subdev_registered,
3936 .unregistered = vin_capture_subdev_unregistered,
3937 };
3938
vin_initialize_capture_subdev(struct vin_core * vinc)3939 int vin_initialize_capture_subdev(struct vin_core *vinc)
3940 {
3941 struct v4l2_subdev *sd = &vinc->vid_cap.subdev;
3942 int ret;
3943
3944 v4l2_subdev_init(sd, &vin_subdev_ops);
3945 sd->grp_id = VIN_GRP_ID_CAPTURE;
3946 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
3947 snprintf(sd->name, sizeof(sd->name), "vin_cap.%d", vinc->id);
3948
3949 vinc->vid_cap.sd_pads[VIN_SD_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
3950 vinc->vid_cap.sd_pads[VIN_SD_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
3951 sd->entity.function = MEDIA_ENT_F_IO_V4L;
3952 ret = media_entity_pads_init(&sd->entity, VIN_SD_PADS_NUM,
3953 vinc->vid_cap.sd_pads);
3954 if (ret)
3955 return ret;
3956
3957 sd->entity.ops = &vin_sd_media_ops;
3958 sd->internal_ops = &vin_capture_sd_internal_ops;
3959 v4l2_set_subdevdata(sd, vinc);
3960 return 0;
3961 }
3962
vin_cleanup_capture_subdev(struct vin_core * vinc)3963 void vin_cleanup_capture_subdev(struct vin_core *vinc)
3964 {
3965 struct v4l2_subdev *sd = &vinc->vid_cap.subdev;
3966
3967 media_entity_cleanup(&sd->entity);
3968 v4l2_set_subdevdata(sd, NULL);
3969 }
3970
3971