• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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