1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Support for Medifield PNW Camera Imaging ISP subsystem.
4  *
5  * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
6  *
7  * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License version
11  * 2 as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  *
19  */
20 
21 #include <linux/module.h>
22 #include <linux/pm_runtime.h>
23 
24 #include <media/v4l2-ioctl.h>
25 #include <media/videobuf-vmalloc.h>
26 
27 #include "atomisp_cmd.h"
28 #include "atomisp_common.h"
29 #include "atomisp_fops.h"
30 #include "atomisp_internal.h"
31 #include "atomisp_ioctl.h"
32 #include "atomisp_compat.h"
33 #include "atomisp_subdev.h"
34 #include "atomisp_v4l2.h"
35 #include "atomisp-regs.h"
36 #include "hmm/hmm.h"
37 
38 #include "type_support.h"
39 #include "device_access/device_access.h"
40 
41 #define ISP_LEFT_PAD			128	/* equal to 2*NWAY */
42 
43 /*
44  * input image data, and current frame resolution for test
45  */
46 #define	ISP_PARAM_MMAP_OFFSET	0xfffff000
47 
48 #define MAGIC_CHECK(is, should)	\
49 	do { \
50 		if (unlikely((is) != (should))) { \
51 			pr_err("magic mismatch: %x (expected %x)\n", \
52 				is, should); \
53 			BUG(); \
54 		} \
55 	} while (0)
56 
57 /*
58  * Videobuf ops
59  */
atomisp_buf_setup(struct videobuf_queue * vq,unsigned int * count,unsigned int * size)60 static int atomisp_buf_setup(struct videobuf_queue *vq, unsigned int *count,
61 			     unsigned int *size)
62 {
63 	struct atomisp_video_pipe *pipe = vq->priv_data;
64 
65 	*size = pipe->pix.sizeimage;
66 
67 	return 0;
68 }
69 
atomisp_buf_prepare(struct videobuf_queue * vq,struct videobuf_buffer * vb,enum v4l2_field field)70 static int atomisp_buf_prepare(struct videobuf_queue *vq,
71 			       struct videobuf_buffer *vb,
72 			       enum v4l2_field field)
73 {
74 	struct atomisp_video_pipe *pipe = vq->priv_data;
75 
76 	vb->size = pipe->pix.sizeimage;
77 	vb->width = pipe->pix.width;
78 	vb->height = pipe->pix.height;
79 	vb->field = field;
80 	vb->state = VIDEOBUF_PREPARED;
81 
82 	return 0;
83 }
84 
atomisp_q_one_metadata_buffer(struct atomisp_sub_device * asd,enum atomisp_input_stream_id stream_id,enum ia_css_pipe_id css_pipe_id)85 static int atomisp_q_one_metadata_buffer(struct atomisp_sub_device *asd,
86 	enum atomisp_input_stream_id stream_id,
87 	enum ia_css_pipe_id css_pipe_id)
88 {
89 	struct atomisp_metadata_buf *metadata_buf;
90 	enum atomisp_metadata_type md_type =
91 	    atomisp_get_metadata_type(asd, css_pipe_id);
92 	struct list_head *metadata_list;
93 
94 	if (asd->metadata_bufs_in_css[stream_id][css_pipe_id] >=
95 	    ATOMISP_CSS_Q_DEPTH)
96 		return 0; /* we have reached CSS queue depth */
97 
98 	if (!list_empty(&asd->metadata[md_type])) {
99 		metadata_list = &asd->metadata[md_type];
100 	} else if (!list_empty(&asd->metadata_ready[md_type])) {
101 		metadata_list = &asd->metadata_ready[md_type];
102 	} else {
103 		dev_warn(asd->isp->dev, "%s: No metadata buffers available for type %d!\n",
104 			 __func__, md_type);
105 		return -EINVAL;
106 	}
107 
108 	metadata_buf = list_entry(metadata_list->next,
109 				  struct atomisp_metadata_buf, list);
110 	list_del_init(&metadata_buf->list);
111 
112 	if (atomisp_q_metadata_buffer_to_css(asd, metadata_buf,
113 					     stream_id, css_pipe_id)) {
114 		list_add(&metadata_buf->list, metadata_list);
115 		return -EINVAL;
116 	} else {
117 		list_add_tail(&metadata_buf->list,
118 			      &asd->metadata_in_css[md_type]);
119 	}
120 	asd->metadata_bufs_in_css[stream_id][css_pipe_id]++;
121 
122 	return 0;
123 }
124 
atomisp_q_one_s3a_buffer(struct atomisp_sub_device * asd,enum atomisp_input_stream_id stream_id,enum ia_css_pipe_id css_pipe_id)125 static int atomisp_q_one_s3a_buffer(struct atomisp_sub_device *asd,
126 				    enum atomisp_input_stream_id stream_id,
127 				    enum ia_css_pipe_id css_pipe_id)
128 {
129 	struct atomisp_s3a_buf *s3a_buf;
130 	struct list_head *s3a_list;
131 	unsigned int exp_id;
132 
133 	if (asd->s3a_bufs_in_css[css_pipe_id] >= ATOMISP_CSS_Q_DEPTH)
134 		return 0; /* we have reached CSS queue depth */
135 
136 	if (!list_empty(&asd->s3a_stats)) {
137 		s3a_list = &asd->s3a_stats;
138 	} else if (!list_empty(&asd->s3a_stats_ready)) {
139 		s3a_list = &asd->s3a_stats_ready;
140 	} else {
141 		dev_warn(asd->isp->dev, "%s: No s3a buffers available!\n",
142 			 __func__);
143 		return -EINVAL;
144 	}
145 
146 	s3a_buf = list_entry(s3a_list->next, struct atomisp_s3a_buf, list);
147 	list_del_init(&s3a_buf->list);
148 	exp_id = s3a_buf->s3a_data->exp_id;
149 
150 	hmm_flush_vmap(s3a_buf->s3a_data->data_ptr);
151 	if (atomisp_q_s3a_buffer_to_css(asd, s3a_buf,
152 					stream_id, css_pipe_id)) {
153 		/* got from head, so return back to the head */
154 		list_add(&s3a_buf->list, s3a_list);
155 		return -EINVAL;
156 	} else {
157 		list_add_tail(&s3a_buf->list, &asd->s3a_stats_in_css);
158 		if (s3a_list == &asd->s3a_stats_ready)
159 			dev_warn(asd->isp->dev, "%s: drop one s3a stat which has exp_id %d!\n",
160 				 __func__, exp_id);
161 	}
162 
163 	asd->s3a_bufs_in_css[css_pipe_id]++;
164 	return 0;
165 }
166 
atomisp_q_one_dis_buffer(struct atomisp_sub_device * asd,enum atomisp_input_stream_id stream_id,enum ia_css_pipe_id css_pipe_id)167 static int atomisp_q_one_dis_buffer(struct atomisp_sub_device *asd,
168 				    enum atomisp_input_stream_id stream_id,
169 				    enum ia_css_pipe_id css_pipe_id)
170 {
171 	struct atomisp_dis_buf *dis_buf;
172 	unsigned long irqflags;
173 
174 	if (asd->dis_bufs_in_css >=  ATOMISP_CSS_Q_DEPTH)
175 		return 0; /* we have reached CSS queue depth */
176 
177 	spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
178 	if (list_empty(&asd->dis_stats)) {
179 		spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
180 		dev_warn(asd->isp->dev, "%s: No dis buffers available!\n",
181 			 __func__);
182 		return -EINVAL;
183 	}
184 
185 	dis_buf = list_entry(asd->dis_stats.prev,
186 			     struct atomisp_dis_buf, list);
187 	list_del_init(&dis_buf->list);
188 	spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
189 
190 	hmm_flush_vmap(dis_buf->dis_data->data_ptr);
191 	if (atomisp_q_dis_buffer_to_css(asd, dis_buf,
192 					stream_id, css_pipe_id)) {
193 		spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
194 		/* got from tail, so return back to the tail */
195 		list_add_tail(&dis_buf->list, &asd->dis_stats);
196 		spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
197 		return -EINVAL;
198 	} else {
199 		spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
200 		list_add_tail(&dis_buf->list, &asd->dis_stats_in_css);
201 		spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
202 	}
203 
204 	asd->dis_bufs_in_css++;
205 
206 	return 0;
207 }
208 
atomisp_q_video_buffers_to_css(struct atomisp_sub_device * asd,struct atomisp_video_pipe * pipe,enum atomisp_input_stream_id stream_id,enum ia_css_buffer_type css_buf_type,enum ia_css_pipe_id css_pipe_id)209 int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd,
210 				   struct atomisp_video_pipe *pipe,
211 				   enum atomisp_input_stream_id stream_id,
212 				   enum ia_css_buffer_type css_buf_type,
213 				   enum ia_css_pipe_id css_pipe_id)
214 {
215 	struct videobuf_vmalloc_memory *vm_mem;
216 	struct atomisp_css_params_with_list *param;
217 	struct ia_css_dvs_grid_info *dvs_grid =
218 	    atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
219 	unsigned long irqflags;
220 	int err = 0;
221 
222 	if (WARN_ON(css_pipe_id >= IA_CSS_PIPE_ID_NUM))
223 		return -EINVAL;
224 
225 	while (pipe->buffers_in_css < ATOMISP_CSS_Q_DEPTH) {
226 		struct videobuf_buffer *vb;
227 
228 		spin_lock_irqsave(&pipe->irq_lock, irqflags);
229 		if (list_empty(&pipe->activeq)) {
230 			spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
231 			return -EINVAL;
232 		}
233 		vb = list_entry(pipe->activeq.next,
234 				struct videobuf_buffer, queue);
235 		list_del_init(&vb->queue);
236 		vb->state = VIDEOBUF_ACTIVE;
237 		spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
238 
239 		/*
240 		 * If there is a per_frame setting to apply on the buffer,
241 		 * do it before buffer en-queueing.
242 		 */
243 		vm_mem = vb->priv;
244 
245 		param = pipe->frame_params[vb->i];
246 		if (param) {
247 			atomisp_makeup_css_parameters(asd,
248 						      &asd->params.css_param.update_flag,
249 						      &param->params);
250 			atomisp_apply_css_parameters(asd, &param->params);
251 
252 			if (param->params.update_flag.dz_config &&
253 			    asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO) {
254 				err = atomisp_calculate_real_zoom_region(asd,
255 					&param->params.dz_config, css_pipe_id);
256 				if (!err)
257 					asd->params.config.dz_config = &param->params.dz_config;
258 			}
259 			atomisp_css_set_isp_config_applied_frame(asd,
260 				vm_mem->vaddr);
261 			atomisp_css_update_isp_params_on_pipe(asd,
262 							      asd->stream_env[stream_id].pipes[css_pipe_id]);
263 			asd->params.dvs_6axis = (struct ia_css_dvs_6axis_config *)
264 						param->params.dvs_6axis;
265 
266 			/*
267 			 * WORKAROUND:
268 			 * Because the camera halv3 can't ensure to set zoom
269 			 * region to per_frame setting and global setting at
270 			 * same time and only set zoom region to pre_frame
271 			 * setting now.so when the pre_frame setting include
272 			 * zoom region,I will set it to global setting.
273 			 */
274 			if (param->params.update_flag.dz_config &&
275 			    asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO
276 			    && !err) {
277 				memcpy(&asd->params.css_param.dz_config,
278 				       &param->params.dz_config,
279 				       sizeof(struct ia_css_dz_config));
280 				asd->params.css_param.update_flag.dz_config =
281 				    (struct atomisp_dz_config *)
282 				    &asd->params.css_param.dz_config;
283 				asd->params.css_update_params_needed = true;
284 			}
285 		}
286 		/* Enqueue buffer */
287 		err = atomisp_q_video_buffer_to_css(asd, vm_mem, stream_id,
288 						    css_buf_type, css_pipe_id);
289 		if (err) {
290 			spin_lock_irqsave(&pipe->irq_lock, irqflags);
291 			list_add_tail(&vb->queue, &pipe->activeq);
292 			vb->state = VIDEOBUF_QUEUED;
293 			spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
294 			dev_err(asd->isp->dev, "%s, css q fails: %d\n",
295 				__func__, err);
296 			return -EINVAL;
297 		}
298 		pipe->buffers_in_css++;
299 
300 		/* enqueue 3A/DIS/metadata buffers */
301 		if (asd->params.curr_grid_info.s3a_grid.enable &&
302 		    css_pipe_id == asd->params.s3a_enabled_pipe &&
303 		    css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
304 			atomisp_q_one_s3a_buffer(asd, stream_id,
305 						 css_pipe_id);
306 
307 		if (asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream_info.
308 		    metadata_info.size &&
309 		    css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
310 			atomisp_q_one_metadata_buffer(asd, stream_id,
311 						      css_pipe_id);
312 
313 		if (dvs_grid && dvs_grid->enable &&
314 		    css_pipe_id == IA_CSS_PIPE_ID_VIDEO &&
315 		    css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
316 			atomisp_q_one_dis_buffer(asd, stream_id,
317 						 css_pipe_id);
318 	}
319 
320 	return 0;
321 }
322 
atomisp_get_css_buf_type(struct atomisp_sub_device * asd,enum ia_css_pipe_id pipe_id,uint16_t source_pad)323 static int atomisp_get_css_buf_type(struct atomisp_sub_device *asd,
324 				    enum ia_css_pipe_id pipe_id,
325 				    uint16_t source_pad)
326 {
327 	if (ATOMISP_USE_YUVPP(asd)) {
328 		/* when run ZSL case */
329 		if (asd->continuous_mode->val &&
330 		    asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
331 			if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE)
332 				return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
333 			else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW)
334 				return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
335 			else
336 				return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
337 		}
338 
339 		/*when run SDV case*/
340 		if (asd->continuous_mode->val &&
341 		    asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
342 			if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE)
343 				return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
344 			else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW)
345 				return IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME;
346 			else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO)
347 				return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
348 			else
349 				return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
350 		}
351 
352 		/*other case: default setting*/
353 		if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE ||
354 		    source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO ||
355 		    (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
356 		     asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO))
357 			return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
358 		else
359 			return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
360 	}
361 
362 	if (pipe_id == IA_CSS_PIPE_ID_COPY ||
363 	    source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE ||
364 	    source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO ||
365 	    (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
366 	     asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO))
367 		return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
368 	else
369 		return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
370 }
371 
372 /* queue all available buffers to css */
atomisp_qbuffers_to_css(struct atomisp_sub_device * asd)373 int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
374 {
375 	enum ia_css_buffer_type buf_type;
376 	enum ia_css_pipe_id css_capture_pipe_id = IA_CSS_PIPE_ID_NUM;
377 	enum ia_css_pipe_id css_preview_pipe_id = IA_CSS_PIPE_ID_NUM;
378 	enum ia_css_pipe_id css_video_pipe_id = IA_CSS_PIPE_ID_NUM;
379 	enum atomisp_input_stream_id input_stream_id;
380 	struct atomisp_video_pipe *capture_pipe = NULL;
381 	struct atomisp_video_pipe *vf_pipe = NULL;
382 	struct atomisp_video_pipe *preview_pipe = NULL;
383 	struct atomisp_video_pipe *video_pipe = NULL;
384 	bool raw_mode = atomisp_is_mbuscode_raw(
385 			    asd->fmt[asd->capture_pad].fmt.code);
386 
387 	if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) {
388 		video_pipe = &asd->video_out_video_capture;
389 		css_video_pipe_id = IA_CSS_PIPE_ID_VIDEO;
390 	} else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) {
391 		preview_pipe = &asd->video_out_capture;
392 		css_preview_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
393 	} else if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
394 		if (asd->continuous_mode->val) {
395 			capture_pipe = &asd->video_out_capture;
396 			vf_pipe = &asd->video_out_vf;
397 			css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
398 		}
399 		video_pipe = &asd->video_out_video_capture;
400 		preview_pipe = &asd->video_out_preview;
401 		css_video_pipe_id = IA_CSS_PIPE_ID_VIDEO;
402 		css_preview_pipe_id = IA_CSS_PIPE_ID_VIDEO;
403 	} else if (asd->continuous_mode->val) {
404 		capture_pipe = &asd->video_out_capture;
405 		vf_pipe = &asd->video_out_vf;
406 		preview_pipe = &asd->video_out_preview;
407 
408 		css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW;
409 		css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
410 	} else if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
411 		preview_pipe = &asd->video_out_preview;
412 		css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW;
413 	} else {
414 		/* ATOMISP_RUN_MODE_STILL_CAPTURE */
415 		capture_pipe = &asd->video_out_capture;
416 		if (!raw_mode)
417 			vf_pipe = &asd->video_out_vf;
418 		css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
419 	}
420 
421 	if (IS_ISP2401 && asd->copy_mode) {
422 		css_capture_pipe_id = IA_CSS_PIPE_ID_COPY;
423 		css_preview_pipe_id = IA_CSS_PIPE_ID_COPY;
424 		css_video_pipe_id = IA_CSS_PIPE_ID_COPY;
425 	}
426 
427 	if (asd->yuvpp_mode) {
428 		capture_pipe = &asd->video_out_capture;
429 		video_pipe   = &asd->video_out_video_capture;
430 		preview_pipe = &asd->video_out_preview;
431 		css_capture_pipe_id = IA_CSS_PIPE_ID_COPY;
432 		css_video_pipe_id   = IA_CSS_PIPE_ID_YUVPP;
433 		css_preview_pipe_id = IA_CSS_PIPE_ID_YUVPP;
434 	}
435 
436 	if (capture_pipe) {
437 		buf_type = atomisp_get_css_buf_type(
438 			       asd, css_capture_pipe_id,
439 			       atomisp_subdev_source_pad(&capture_pipe->vdev));
440 		input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
441 
442 		/*
443 		 * use yuvpp pipe for SOC camera.
444 		 */
445 		if (ATOMISP_USE_YUVPP(asd))
446 			css_capture_pipe_id = IA_CSS_PIPE_ID_YUVPP;
447 
448 		atomisp_q_video_buffers_to_css(asd, capture_pipe,
449 					       input_stream_id,
450 					       buf_type, css_capture_pipe_id);
451 	}
452 
453 	if (vf_pipe) {
454 		buf_type = atomisp_get_css_buf_type(
455 			       asd, css_capture_pipe_id,
456 			       atomisp_subdev_source_pad(&vf_pipe->vdev));
457 		if (asd->stream_env[ATOMISP_INPUT_STREAM_POSTVIEW].stream)
458 			input_stream_id = ATOMISP_INPUT_STREAM_POSTVIEW;
459 		else
460 			input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
461 
462 		/*
463 		 * use yuvpp pipe for SOC camera.
464 		 */
465 		if (ATOMISP_USE_YUVPP(asd))
466 			css_capture_pipe_id = IA_CSS_PIPE_ID_YUVPP;
467 		atomisp_q_video_buffers_to_css(asd, vf_pipe,
468 					       input_stream_id,
469 					       buf_type, css_capture_pipe_id);
470 	}
471 
472 	if (preview_pipe) {
473 		buf_type = atomisp_get_css_buf_type(
474 			       asd, css_preview_pipe_id,
475 			       atomisp_subdev_source_pad(&preview_pipe->vdev));
476 		if (ATOMISP_SOC_CAMERA(asd) && css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP)
477 			input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
478 		/* else for ext isp use case */
479 		else if (css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP)
480 			input_stream_id = ATOMISP_INPUT_STREAM_VIDEO;
481 		else if (asd->stream_env[ATOMISP_INPUT_STREAM_PREVIEW].stream)
482 			input_stream_id = ATOMISP_INPUT_STREAM_PREVIEW;
483 		else
484 			input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
485 
486 		/*
487 		 * use yuvpp pipe for SOC camera.
488 		 */
489 		if (ATOMISP_USE_YUVPP(asd))
490 			css_preview_pipe_id = IA_CSS_PIPE_ID_YUVPP;
491 
492 		atomisp_q_video_buffers_to_css(asd, preview_pipe,
493 					       input_stream_id,
494 					       buf_type, css_preview_pipe_id);
495 	}
496 
497 	if (video_pipe) {
498 		buf_type = atomisp_get_css_buf_type(
499 			       asd, css_video_pipe_id,
500 			       atomisp_subdev_source_pad(&video_pipe->vdev));
501 		if (asd->stream_env[ATOMISP_INPUT_STREAM_VIDEO].stream)
502 			input_stream_id = ATOMISP_INPUT_STREAM_VIDEO;
503 		else
504 			input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
505 
506 		/*
507 		 * use yuvpp pipe for SOC camera.
508 		 */
509 		if (ATOMISP_USE_YUVPP(asd))
510 			css_video_pipe_id = IA_CSS_PIPE_ID_YUVPP;
511 
512 		atomisp_q_video_buffers_to_css(asd, video_pipe,
513 					       input_stream_id,
514 					       buf_type, css_video_pipe_id);
515 	}
516 
517 	return 0;
518 }
519 
atomisp_buf_queue(struct videobuf_queue * vq,struct videobuf_buffer * vb)520 static void atomisp_buf_queue(struct videobuf_queue *vq,
521 			      struct videobuf_buffer *vb)
522 {
523 	struct atomisp_video_pipe *pipe = vq->priv_data;
524 
525 	/*
526 	 * when a frame buffer meets following conditions, it should be put into
527 	 * the waiting list:
528 	 * 1.  It is not a main output frame, and it has a per-frame parameter
529 	 *     to go with it.
530 	 * 2.  It is not a main output frame, and the waiting buffer list is not
531 	 *     empty, to keep the FIFO sequence of frame buffer processing, it
532 	 *     is put to waiting list until previous per-frame parameter buffers
533 	 *     get enqueued.
534 	 */
535 	if (!atomisp_is_vf_pipe(pipe) &&
536 	    (pipe->frame_request_config_id[vb->i] ||
537 	     !list_empty(&pipe->buffers_waiting_for_param)))
538 		list_add_tail(&vb->queue, &pipe->buffers_waiting_for_param);
539 	else
540 		list_add_tail(&vb->queue, &pipe->activeq);
541 
542 	vb->state = VIDEOBUF_QUEUED;
543 }
544 
atomisp_buf_release(struct videobuf_queue * vq,struct videobuf_buffer * vb)545 static void atomisp_buf_release(struct videobuf_queue *vq,
546 				struct videobuf_buffer *vb)
547 {
548 	vb->state = VIDEOBUF_NEEDS_INIT;
549 	atomisp_videobuf_free_buf(vb);
550 }
551 
552 static const struct videobuf_queue_ops videobuf_qops = {
553 	.buf_setup	= atomisp_buf_setup,
554 	.buf_prepare	= atomisp_buf_prepare,
555 	.buf_queue	= atomisp_buf_queue,
556 	.buf_release	= atomisp_buf_release,
557 };
558 
atomisp_init_pipe(struct atomisp_video_pipe * pipe)559 static int atomisp_init_pipe(struct atomisp_video_pipe *pipe)
560 {
561 	/* init locks */
562 	spin_lock_init(&pipe->irq_lock);
563 
564 	videobuf_queue_vmalloc_init(&pipe->capq, &videobuf_qops, NULL,
565 				    &pipe->irq_lock,
566 				    V4L2_BUF_TYPE_VIDEO_CAPTURE,
567 				    V4L2_FIELD_NONE,
568 				    sizeof(struct atomisp_buffer), pipe,
569 				    NULL);	/* ext_lock: NULL */
570 
571 	INIT_LIST_HEAD(&pipe->activeq);
572 	INIT_LIST_HEAD(&pipe->buffers_waiting_for_param);
573 	INIT_LIST_HEAD(&pipe->per_frame_params);
574 	memset(pipe->frame_request_config_id, 0,
575 	       VIDEO_MAX_FRAME * sizeof(unsigned int));
576 	memset(pipe->frame_params, 0,
577 	       VIDEO_MAX_FRAME *
578 	       sizeof(struct atomisp_css_params_with_list *));
579 
580 	return 0;
581 }
582 
atomisp_dev_init_struct(struct atomisp_device * isp)583 static void atomisp_dev_init_struct(struct atomisp_device *isp)
584 {
585 	unsigned int i;
586 
587 	isp->need_gfx_throttle = true;
588 	isp->isp_fatal_error = false;
589 	isp->mipi_frame_size = 0;
590 
591 	for (i = 0; i < isp->input_cnt; i++)
592 		isp->inputs[i].asd = NULL;
593 	/*
594 	 * For Merrifield, frequency is scalable.
595 	 * After boot-up, the default frequency is 200MHz.
596 	 */
597 	isp->sw_contex.running_freq = ISP_FREQ_200MHZ;
598 }
599 
atomisp_subdev_init_struct(struct atomisp_sub_device * asd)600 static void atomisp_subdev_init_struct(struct atomisp_sub_device *asd)
601 {
602 	v4l2_ctrl_s_ctrl(asd->run_mode, ATOMISP_RUN_MODE_STILL_CAPTURE);
603 	memset(&asd->params.css_param, 0, sizeof(asd->params.css_param));
604 	asd->params.color_effect = V4L2_COLORFX_NONE;
605 	asd->params.bad_pixel_en = true;
606 	asd->params.gdc_cac_en = false;
607 	asd->params.video_dis_en = false;
608 	asd->params.sc_en = false;
609 	asd->params.fpn_en = false;
610 	asd->params.xnr_en = false;
611 	asd->params.false_color = 0;
612 	asd->params.online_process = 1;
613 	asd->params.yuv_ds_en = 0;
614 	/* s3a grid not enabled for any pipe */
615 	asd->params.s3a_enabled_pipe = IA_CSS_PIPE_ID_NUM;
616 
617 	asd->params.offline_parm.num_captures = 1;
618 	asd->params.offline_parm.skip_frames = 0;
619 	asd->params.offline_parm.offset = 0;
620 	asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
621 	/* Add for channel */
622 	asd->input_curr = 0;
623 
624 	asd->mipi_frame_size = 0;
625 	asd->copy_mode = false;
626 	asd->yuvpp_mode = false;
627 
628 	asd->stream_prepared = false;
629 	asd->high_speed_mode = false;
630 	asd->sensor_array_res.height = 0;
631 	asd->sensor_array_res.width = 0;
632 	atomisp_css_init_struct(asd);
633 }
634 
635 /*
636  * file operation functions
637  */
atomisp_subdev_users(struct atomisp_sub_device * asd)638 static unsigned int atomisp_subdev_users(struct atomisp_sub_device *asd)
639 {
640 	return asd->video_out_preview.users +
641 	       asd->video_out_vf.users +
642 	       asd->video_out_capture.users +
643 	       asd->video_out_video_capture.users;
644 }
645 
atomisp_dev_users(struct atomisp_device * isp)646 unsigned int atomisp_dev_users(struct atomisp_device *isp)
647 {
648 	unsigned int i, sum;
649 
650 	for (i = 0, sum = 0; i < isp->num_of_streams; i++)
651 		sum += atomisp_subdev_users(&isp->asd[i]);
652 
653 	return sum;
654 }
655 
atomisp_open(struct file * file)656 static int atomisp_open(struct file *file)
657 {
658 	struct video_device *vdev = video_devdata(file);
659 	struct atomisp_device *isp = video_get_drvdata(vdev);
660 	struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
661 	struct atomisp_sub_device *asd = pipe->asd;
662 	int ret;
663 
664 	dev_dbg(isp->dev, "open device %s\n", vdev->name);
665 
666 	ret = v4l2_fh_open(file);
667 	if (ret)
668 		return ret;
669 
670 	mutex_lock(&isp->mutex);
671 
672 	asd->subdev.devnode = vdev;
673 	/* Deferred firmware loading case. */
674 	if (isp->css_env.isp_css_fw.bytes == 0) {
675 		dev_err(isp->dev, "Deferred firmware load.\n");
676 		isp->firmware = atomisp_load_firmware(isp);
677 		if (!isp->firmware) {
678 			dev_err(isp->dev, "Failed to load ISP firmware.\n");
679 			ret = -ENOENT;
680 			goto error;
681 		}
682 		ret = atomisp_css_load_firmware(isp);
683 		if (ret) {
684 			dev_err(isp->dev, "Failed to init css.\n");
685 			goto error;
686 		}
687 		/* No need to keep FW in memory anymore. */
688 		release_firmware(isp->firmware);
689 		isp->firmware = NULL;
690 		isp->css_env.isp_css_fw.data = NULL;
691 	}
692 
693 	if (!isp->input_cnt) {
694 		dev_err(isp->dev, "no camera attached\n");
695 		ret = -EINVAL;
696 		goto error;
697 	}
698 
699 	/*
700 	 * atomisp does not allow multiple open
701 	 */
702 	if (pipe->users) {
703 		dev_dbg(isp->dev, "video node already opened\n");
704 		mutex_unlock(&isp->mutex);
705 		return -EBUSY;
706 	}
707 
708 	ret = atomisp_init_pipe(pipe);
709 	if (ret)
710 		goto error;
711 
712 	if (atomisp_dev_users(isp)) {
713 		dev_dbg(isp->dev, "skip init isp in open\n");
714 		goto init_subdev;
715 	}
716 
717 	/* runtime power management, turn on ISP */
718 	ret = pm_runtime_resume_and_get(vdev->v4l2_dev->dev);
719 	if (ret < 0) {
720 		dev_err(isp->dev, "Failed to power on device\n");
721 		goto error;
722 	}
723 
724 	/* Init ISP */
725 	if (atomisp_css_init(isp)) {
726 		ret = -EINVAL;
727 		/* Need to clean up CSS init if it fails. */
728 		goto css_error;
729 	}
730 
731 	atomisp_dev_init_struct(isp);
732 
733 	ret = v4l2_subdev_call(isp->flash, core, s_power, 1);
734 	if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD) {
735 		dev_err(isp->dev, "Failed to power-on flash\n");
736 		goto css_error;
737 	}
738 
739 init_subdev:
740 	if (atomisp_subdev_users(asd))
741 		goto done;
742 
743 	atomisp_subdev_init_struct(asd);
744 
745 done:
746 	pipe->users++;
747 	mutex_unlock(&isp->mutex);
748 
749 	/* Ensure that a mode is set */
750 	v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode);
751 
752 	return 0;
753 
754 css_error:
755 	atomisp_css_uninit(isp);
756 	pm_runtime_put(vdev->v4l2_dev->dev);
757 error:
758 	mutex_unlock(&isp->mutex);
759 	v4l2_fh_release(file);
760 	return ret;
761 }
762 
atomisp_release(struct file * file)763 static int atomisp_release(struct file *file)
764 {
765 	struct video_device *vdev = video_devdata(file);
766 	struct atomisp_device *isp = video_get_drvdata(vdev);
767 	struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
768 	struct atomisp_sub_device *asd = pipe->asd;
769 	struct v4l2_requestbuffers req;
770 	struct v4l2_subdev_fh fh;
771 	struct v4l2_rect clear_compose = {0};
772 	unsigned long flags;
773 	int ret = 0;
774 
775 	v4l2_fh_init(&fh.vfh, vdev);
776 
777 	req.count = 0;
778 	if (!isp)
779 		return -EBADF;
780 
781 	mutex_lock(&isp->mutex);
782 
783 	dev_dbg(isp->dev, "release device %s\n", vdev->name);
784 
785 	asd->subdev.devnode = vdev;
786 
787 	pipe->users--;
788 
789 	if (pipe->capq.streaming)
790 		dev_warn(isp->dev,
791 			 "%s: ISP still streaming while closing!",
792 			 __func__);
793 
794 	if (pipe->capq.streaming &&
795 	    atomisp_streamoff(file, NULL, V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
796 		dev_err(isp->dev, "atomisp_streamoff failed on release, driver bug");
797 		goto done;
798 	}
799 
800 	if (pipe->users)
801 		goto done;
802 
803 	if (atomisp_reqbufs(file, NULL, &req)) {
804 		dev_err(isp->dev, "atomisp_reqbufs failed on release, driver bug");
805 		goto done;
806 	}
807 
808 	/*
809 	 * A little trick here:
810 	 * file injection input resolution is recorded in the sink pad,
811 	 * therefore can not be cleared when releaseing one device node.
812 	 * The sink pad setting can only be cleared when all device nodes
813 	 * get released.
814 	 */
815 	if (asd->fmt_auto->val) {
816 		struct v4l2_mbus_framefmt isp_sink_fmt = { 0 };
817 
818 		atomisp_subdev_set_ffmt(&asd->subdev, fh.state,
819 					V4L2_SUBDEV_FORMAT_ACTIVE,
820 					ATOMISP_SUBDEV_PAD_SINK, &isp_sink_fmt);
821 	}
822 
823 	if (atomisp_subdev_users(asd))
824 		goto done;
825 
826 	atomisp_css_free_stat_buffers(asd);
827 	atomisp_free_internal_buffers(asd);
828 	ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
829 			       core, s_power, 0);
830 	if (ret)
831 		dev_warn(isp->dev, "Failed to power-off sensor\n");
832 
833 	/* clear the asd field to show this camera is not used */
834 	isp->inputs[asd->input_curr].asd = NULL;
835 	spin_lock_irqsave(&isp->lock, flags);
836 	asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
837 	spin_unlock_irqrestore(&isp->lock, flags);
838 
839 	if (atomisp_dev_users(isp))
840 		goto done;
841 
842 	atomisp_destroy_pipes_stream_force(asd);
843 	atomisp_css_uninit(isp);
844 
845 	if (defer_fw_load) {
846 		ia_css_unload_firmware();
847 		isp->css_env.isp_css_fw.data = NULL;
848 		isp->css_env.isp_css_fw.bytes = 0;
849 	}
850 
851 	ret = v4l2_subdev_call(isp->flash, core, s_power, 0);
852 	if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD)
853 		dev_warn(isp->dev, "Failed to power-off flash\n");
854 
855 	if (pm_runtime_put_sync(vdev->v4l2_dev->dev) < 0)
856 		dev_err(isp->dev, "Failed to power off device\n");
857 
858 done:
859 	atomisp_subdev_set_selection(&asd->subdev, fh.state,
860 				     V4L2_SUBDEV_FORMAT_ACTIVE,
861 				     atomisp_subdev_source_pad(vdev),
862 				     V4L2_SEL_TGT_COMPOSE, 0,
863 				     &clear_compose);
864 	mutex_unlock(&isp->mutex);
865 
866 	return v4l2_fh_release(file);
867 }
868 
869 /*
870  * Memory help functions for image frame and private parameters
871  */
do_isp_mm_remap(struct atomisp_device * isp,struct vm_area_struct * vma,ia_css_ptr isp_virt,u32 host_virt,u32 pgnr)872 static int do_isp_mm_remap(struct atomisp_device *isp,
873 			   struct vm_area_struct *vma,
874 			   ia_css_ptr isp_virt, u32 host_virt, u32 pgnr)
875 {
876 	u32 pfn;
877 
878 	while (pgnr) {
879 		pfn = hmm_virt_to_phys(isp_virt) >> PAGE_SHIFT;
880 		if (remap_pfn_range(vma, host_virt, pfn,
881 				    PAGE_SIZE, PAGE_SHARED)) {
882 			dev_err(isp->dev, "remap_pfn_range err.\n");
883 			return -EAGAIN;
884 		}
885 
886 		isp_virt += PAGE_SIZE;
887 		host_virt += PAGE_SIZE;
888 		pgnr--;
889 	}
890 
891 	return 0;
892 }
893 
frame_mmap(struct atomisp_device * isp,const struct ia_css_frame * frame,struct vm_area_struct * vma)894 static int frame_mmap(struct atomisp_device *isp,
895 		      const struct ia_css_frame *frame, struct vm_area_struct *vma)
896 {
897 	ia_css_ptr isp_virt;
898 	u32 host_virt;
899 	u32 pgnr;
900 
901 	if (!frame) {
902 		dev_err(isp->dev, "%s: NULL frame pointer.\n", __func__);
903 		return -EINVAL;
904 	}
905 
906 	host_virt = vma->vm_start;
907 	isp_virt = frame->data;
908 	pgnr = DIV_ROUND_UP(frame->data_bytes, PAGE_SIZE);
909 
910 	if (do_isp_mm_remap(isp, vma, isp_virt, host_virt, pgnr))
911 		return -EAGAIN;
912 
913 	return 0;
914 }
915 
atomisp_videobuf_mmap_mapper(struct videobuf_queue * q,struct vm_area_struct * vma)916 int atomisp_videobuf_mmap_mapper(struct videobuf_queue *q,
917 				 struct vm_area_struct *vma)
918 {
919 	u32 offset = vma->vm_pgoff << PAGE_SHIFT;
920 	int ret = -EINVAL, i;
921 	struct atomisp_device *isp =
922 	    ((struct atomisp_video_pipe *)(q->priv_data))->isp;
923 	struct videobuf_vmalloc_memory *vm_mem;
924 	struct videobuf_mapping *map;
925 
926 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
927 	if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) {
928 		dev_err(isp->dev, "map appl bug: PROT_WRITE and MAP_SHARED are required\n");
929 		return -EINVAL;
930 	}
931 
932 	mutex_lock(&q->vb_lock);
933 	for (i = 0; i < VIDEO_MAX_FRAME; i++) {
934 		struct videobuf_buffer *buf = q->bufs[i];
935 
936 		if (!buf)
937 			continue;
938 
939 		map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
940 		if (!map) {
941 			mutex_unlock(&q->vb_lock);
942 			return -ENOMEM;
943 		}
944 
945 		buf->map = map;
946 		map->q = q;
947 
948 		buf->baddr = vma->vm_start;
949 
950 		if (buf && buf->memory == V4L2_MEMORY_MMAP &&
951 		    buf->boff == offset) {
952 			vm_mem = buf->priv;
953 			ret = frame_mmap(isp, vm_mem->vaddr, vma);
954 			vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
955 			break;
956 		}
957 	}
958 	mutex_unlock(&q->vb_lock);
959 
960 	return ret;
961 }
962 
963 /* The input frame contains left and right padding that need to be removed.
964  * There is always ISP_LEFT_PAD padding on the left side.
965  * There is also padding on the right (padded_width - width).
966  */
remove_pad_from_frame(struct atomisp_device * isp,struct ia_css_frame * in_frame,__u32 width,__u32 height)967 static int remove_pad_from_frame(struct atomisp_device *isp,
968 				 struct ia_css_frame *in_frame, __u32 width, __u32 height)
969 {
970 	unsigned int i;
971 	unsigned short *buffer;
972 	int ret = 0;
973 	ia_css_ptr load = in_frame->data;
974 	ia_css_ptr store = load;
975 
976 	buffer = kmalloc_array(width, sizeof(load), GFP_KERNEL);
977 	if (!buffer)
978 		return -ENOMEM;
979 
980 	load += ISP_LEFT_PAD;
981 	for (i = 0; i < height; i++) {
982 		ret = hmm_load(load, buffer, width * sizeof(load));
983 		if (ret < 0)
984 			goto remove_pad_error;
985 
986 		ret = hmm_store(store, buffer, width * sizeof(store));
987 		if (ret < 0)
988 			goto remove_pad_error;
989 
990 		load  += in_frame->info.padded_width;
991 		store += width;
992 	}
993 
994 remove_pad_error:
995 	kfree(buffer);
996 	return ret;
997 }
998 
atomisp_mmap(struct file * file,struct vm_area_struct * vma)999 static int atomisp_mmap(struct file *file, struct vm_area_struct *vma)
1000 {
1001 	struct video_device *vdev = video_devdata(file);
1002 	struct atomisp_device *isp = video_get_drvdata(vdev);
1003 	struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1004 	struct atomisp_sub_device *asd = pipe->asd;
1005 	struct ia_css_frame *raw_virt_addr;
1006 	u32 start = vma->vm_start;
1007 	u32 end = vma->vm_end;
1008 	u32 size = end - start;
1009 	u32 origin_size, new_size;
1010 	int ret;
1011 
1012 	if (!asd) {
1013 		dev_err(isp->dev, "%s(): asd is NULL, device is %s\n",
1014 			__func__, vdev->name);
1015 		return -EINVAL;
1016 	}
1017 
1018 	if (!(vma->vm_flags & (VM_WRITE | VM_READ)))
1019 		return -EACCES;
1020 
1021 	mutex_lock(&isp->mutex);
1022 
1023 	if (!(vma->vm_flags & VM_SHARED)) {
1024 		/* Map private buffer.
1025 		 * Set VM_SHARED to the flags since we need
1026 		 * to map the buffer page by page.
1027 		 * Without VM_SHARED, remap_pfn_range() treats
1028 		 * this kind of mapping as invalid.
1029 		 */
1030 		vma->vm_flags |= VM_SHARED;
1031 		ret = hmm_mmap(vma, vma->vm_pgoff << PAGE_SHIFT);
1032 		mutex_unlock(&isp->mutex);
1033 		return ret;
1034 	}
1035 
1036 	/* mmap for ISP offline raw data */
1037 	if (atomisp_subdev_source_pad(vdev)
1038 	    == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE &&
1039 	    vma->vm_pgoff == (ISP_PARAM_MMAP_OFFSET >> PAGE_SHIFT)) {
1040 		new_size = pipe->pix.width * pipe->pix.height * 2;
1041 		if (asd->params.online_process != 0) {
1042 			ret = -EINVAL;
1043 			goto error;
1044 		}
1045 		raw_virt_addr = asd->raw_output_frame;
1046 		if (!raw_virt_addr) {
1047 			dev_err(isp->dev, "Failed to request RAW frame\n");
1048 			ret = -EINVAL;
1049 			goto error;
1050 		}
1051 
1052 		ret = remove_pad_from_frame(isp, raw_virt_addr,
1053 					    pipe->pix.width, pipe->pix.height);
1054 		if (ret < 0) {
1055 			dev_err(isp->dev, "remove pad failed.\n");
1056 			goto error;
1057 		}
1058 		origin_size = raw_virt_addr->data_bytes;
1059 		raw_virt_addr->data_bytes = new_size;
1060 
1061 		if (size != PAGE_ALIGN(new_size)) {
1062 			dev_err(isp->dev, "incorrect size for mmap ISP  Raw Frame\n");
1063 			ret = -EINVAL;
1064 			goto error;
1065 		}
1066 
1067 		if (frame_mmap(isp, raw_virt_addr, vma)) {
1068 			dev_err(isp->dev, "frame_mmap failed.\n");
1069 			raw_virt_addr->data_bytes = origin_size;
1070 			ret = -EAGAIN;
1071 			goto error;
1072 		}
1073 		raw_virt_addr->data_bytes = origin_size;
1074 		vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
1075 		mutex_unlock(&isp->mutex);
1076 		return 0;
1077 	}
1078 
1079 	/*
1080 	 * mmap for normal frames
1081 	 */
1082 	if (size != pipe->pix.sizeimage) {
1083 		dev_err(isp->dev, "incorrect size for mmap ISP frames\n");
1084 		ret = -EINVAL;
1085 		goto error;
1086 	}
1087 	mutex_unlock(&isp->mutex);
1088 
1089 	return atomisp_videobuf_mmap_mapper(&pipe->capq, vma);
1090 
1091 error:
1092 	mutex_unlock(&isp->mutex);
1093 
1094 	return ret;
1095 }
1096 
atomisp_poll(struct file * file,struct poll_table_struct * pt)1097 static __poll_t atomisp_poll(struct file *file,
1098 			     struct poll_table_struct *pt)
1099 {
1100 	struct video_device *vdev = video_devdata(file);
1101 	struct atomisp_device *isp = video_get_drvdata(vdev);
1102 	struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1103 
1104 	mutex_lock(&isp->mutex);
1105 	if (pipe->capq.streaming != 1) {
1106 		mutex_unlock(&isp->mutex);
1107 		return EPOLLERR;
1108 	}
1109 	mutex_unlock(&isp->mutex);
1110 
1111 	return videobuf_poll_stream(file, &pipe->capq, pt);
1112 }
1113 
1114 const struct v4l2_file_operations atomisp_fops = {
1115 	.owner = THIS_MODULE,
1116 	.open = atomisp_open,
1117 	.release = atomisp_release,
1118 	.mmap = atomisp_mmap,
1119 	.unlocked_ioctl = video_ioctl2,
1120 #ifdef CONFIG_COMPAT
1121 	/*
1122 	 * this was removed because of bugs, the interface
1123 	 * needs to be made safe for compat tasks instead.
1124 	.compat_ioctl32 = atomisp_compat_ioctl32,
1125 	 */
1126 #endif
1127 	.poll = atomisp_poll,
1128 };
1129