1 /*
2  * Support for Medifield PNW Camera Imaging ISP subsystem.
3  *
4  * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License version
8  * 2 as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  *
16  */
17 #include <linux/module.h>
18 #include <linux/uaccess.h>
19 #include <linux/delay.h>
20 #include <linux/device.h>
21 #include <linux/mm.h>
22 #include <linux/sched.h>
23 #include <linux/slab.h>
24 
25 #include <media/v4l2-event.h>
26 #include <media/v4l2-mediabus.h>
27 #include "atomisp_cmd.h"
28 #include "atomisp_common.h"
29 #include "atomisp_compat.h"
30 #include "atomisp_internal.h"
31 
32 const struct atomisp_in_fmt_conv atomisp_in_fmt_conv[] = {
33 	{ MEDIA_BUS_FMT_SBGGR8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, CSS_BAYER_ORDER_BGGR, CSS_FORMAT_RAW_8 },
34 	{ MEDIA_BUS_FMT_SGBRG8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, CSS_BAYER_ORDER_GBRG, CSS_FORMAT_RAW_8 },
35 	{ MEDIA_BUS_FMT_SGRBG8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, CSS_BAYER_ORDER_GRBG, CSS_FORMAT_RAW_8 },
36 	{ MEDIA_BUS_FMT_SRGGB8_1X8, 8, 8, ATOMISP_INPUT_FORMAT_RAW_8, CSS_BAYER_ORDER_RGGB, CSS_FORMAT_RAW_8 },
37 	{ MEDIA_BUS_FMT_SBGGR10_1X10, 10, 10, ATOMISP_INPUT_FORMAT_RAW_10, CSS_BAYER_ORDER_BGGR, CSS_FORMAT_RAW_10 },
38 	{ MEDIA_BUS_FMT_SGBRG10_1X10, 10, 10, ATOMISP_INPUT_FORMAT_RAW_10, CSS_BAYER_ORDER_GBRG, CSS_FORMAT_RAW_10 },
39 	{ MEDIA_BUS_FMT_SGRBG10_1X10, 10, 10, ATOMISP_INPUT_FORMAT_RAW_10, CSS_BAYER_ORDER_GRBG, CSS_FORMAT_RAW_10 },
40 	{ MEDIA_BUS_FMT_SRGGB10_1X10, 10, 10, ATOMISP_INPUT_FORMAT_RAW_10, CSS_BAYER_ORDER_RGGB, CSS_FORMAT_RAW_10 },
41 	{ MEDIA_BUS_FMT_SBGGR12_1X12, 12, 12, ATOMISP_INPUT_FORMAT_RAW_12, CSS_BAYER_ORDER_BGGR, CSS_FORMAT_RAW_12 },
42 	{ MEDIA_BUS_FMT_SGBRG12_1X12, 12, 12, ATOMISP_INPUT_FORMAT_RAW_12, CSS_BAYER_ORDER_GBRG, CSS_FORMAT_RAW_12 },
43 	{ MEDIA_BUS_FMT_SGRBG12_1X12, 12, 12, ATOMISP_INPUT_FORMAT_RAW_12, CSS_BAYER_ORDER_GRBG, CSS_FORMAT_RAW_12 },
44 	{ MEDIA_BUS_FMT_SRGGB12_1X12, 12, 12, ATOMISP_INPUT_FORMAT_RAW_12, CSS_BAYER_ORDER_RGGB, CSS_FORMAT_RAW_12 },
45 	{ MEDIA_BUS_FMT_UYVY8_1X16, 8, 8, ATOMISP_INPUT_FORMAT_YUV422_8, 0, ATOMISP_INPUT_FORMAT_YUV422_8 },
46 	{ MEDIA_BUS_FMT_YUYV8_1X16, 8, 8, ATOMISP_INPUT_FORMAT_YUV422_8, 0, ATOMISP_INPUT_FORMAT_YUV422_8 },
47 	{ MEDIA_BUS_FMT_JPEG_1X8, 8, 8, CSS_FRAME_FORMAT_BINARY_8, 0, ATOMISP_INPUT_FORMAT_BINARY_8 },
48 	{ V4L2_MBUS_FMT_CUSTOM_NV12, 12, 12, CSS_FRAME_FORMAT_NV12, 0, CSS_FRAME_FORMAT_NV12 },
49 	{ V4L2_MBUS_FMT_CUSTOM_NV21, 12, 12, CSS_FRAME_FORMAT_NV21, 0, CSS_FRAME_FORMAT_NV21 },
50 	{ V4L2_MBUS_FMT_CUSTOM_YUV420, 12, 12, ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY, 0, ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY },
51 #if 0
52 	{ V4L2_MBUS_FMT_CUSTOM_M10MO_RAW, 8, 8, CSS_FRAME_FORMAT_BINARY_8, 0, ATOMISP_INPUT_FORMAT_BINARY_8 },
53 #endif
54 	/* no valid V4L2 MBUS code for metadata format, so leave it 0. */
55 	{ 0, 0, 0, ATOMISP_INPUT_FORMAT_EMBEDDED, 0, ATOMISP_INPUT_FORMAT_EMBEDDED },
56 	{}
57 };
58 
59 static const struct {
60 	u32 code;
61 	u32 compressed;
62 } compressed_codes[] = {
63 	{ MEDIA_BUS_FMT_SBGGR10_1X10, MEDIA_BUS_FMT_SBGGR10_DPCM8_1X8 },
64 	{ MEDIA_BUS_FMT_SGBRG10_1X10, MEDIA_BUS_FMT_SGBRG10_DPCM8_1X8 },
65 	{ MEDIA_BUS_FMT_SGRBG10_1X10, MEDIA_BUS_FMT_SGRBG10_DPCM8_1X8 },
66 	{ MEDIA_BUS_FMT_SRGGB10_1X10, MEDIA_BUS_FMT_SRGGB10_DPCM8_1X8 },
67 };
68 
69 u32 atomisp_subdev_uncompressed_code(u32 code)
70 {
71 	unsigned int i;
72 
73 	for (i = 0; i < ARRAY_SIZE(compressed_codes); i++)
74 		if (code == compressed_codes[i].compressed)
75 			return compressed_codes[i].code;
76 
77 	return code;
78 }
79 
80 bool atomisp_subdev_is_compressed(u32 code)
81 {
82 	int i;
83 
84 	for (i = 0; i < ARRAY_SIZE(atomisp_in_fmt_conv) - 1; i++)
85 		if (code == atomisp_in_fmt_conv[i].code)
86 			return atomisp_in_fmt_conv[i].bpp !=
87 			       atomisp_in_fmt_conv[i].depth;
88 
89 	return false;
90 }
91 
92 const struct atomisp_in_fmt_conv *atomisp_find_in_fmt_conv(u32 code)
93 {
94 	int i;
95 
96 	for (i = 0; i < ARRAY_SIZE(atomisp_in_fmt_conv) - 1; i++)
97 		if (code == atomisp_in_fmt_conv[i].code)
98 			return atomisp_in_fmt_conv + i;
99 
100 	return NULL;
101 }
102 
103 const struct atomisp_in_fmt_conv *atomisp_find_in_fmt_conv_by_atomisp_in_fmt(
104     enum atomisp_input_format atomisp_in_fmt)
105 {
106 	int i;
107 
108 	for (i = 0; i < ARRAY_SIZE(atomisp_in_fmt_conv) - 1; i++)
109 		if (atomisp_in_fmt_conv[i].atomisp_in_fmt == atomisp_in_fmt)
110 			return atomisp_in_fmt_conv + i;
111 
112 	return NULL;
113 }
114 
115 bool atomisp_subdev_format_conversion(struct atomisp_sub_device *asd,
116 				      unsigned int source_pad)
117 {
118 	struct v4l2_mbus_framefmt *sink, *src;
119 
120 	sink = atomisp_subdev_get_ffmt(&asd->subdev, NULL,
121 				       V4L2_SUBDEV_FORMAT_ACTIVE,
122 				       ATOMISP_SUBDEV_PAD_SINK);
123 	src = atomisp_subdev_get_ffmt(&asd->subdev, NULL,
124 				      V4L2_SUBDEV_FORMAT_ACTIVE, source_pad);
125 
126 	return atomisp_is_mbuscode_raw(sink->code)
127 	       && !atomisp_is_mbuscode_raw(src->code);
128 }
129 
130 uint16_t atomisp_subdev_source_pad(struct video_device *vdev)
131 {
132 	struct media_link *link;
133 	u16 ret = 0;
134 
135 	list_for_each_entry(link, &vdev->entity.links, list) {
136 		if (link->source) {
137 			ret = link->source->index;
138 			break;
139 		}
140 	}
141 	return ret;
142 }
143 
144 /*
145  * V4L2 subdev operations
146  */
147 
148 /*
149  * isp_subdev_ioctl - CCDC module private ioctl's
150  * @sd: ISP V4L2 subdevice
151  * @cmd: ioctl command
152  * @arg: ioctl argument
153  *
154  * Return 0 on success or a negative error code otherwise.
155  */
156 static long isp_subdev_ioctl(struct v4l2_subdev *sd,
157 			     unsigned int cmd, void *arg)
158 {
159 	return 0;
160 }
161 
162 /*
163  * isp_subdev_set_power - Power on/off the CCDC module
164  * @sd: ISP V4L2 subdevice
165  * @on: power on/off
166  *
167  * Return 0 on success or a negative error code otherwise.
168  */
169 static int isp_subdev_set_power(struct v4l2_subdev *sd, int on)
170 {
171 	return 0;
172 }
173 
174 static int isp_subdev_subscribe_event(struct v4l2_subdev *sd,
175 				      struct v4l2_fh *fh,
176 				      struct v4l2_event_subscription *sub)
177 {
178 	struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd);
179 	struct atomisp_device *isp = isp_sd->isp;
180 
181 	if (sub->type != V4L2_EVENT_FRAME_SYNC &&
182 	    sub->type != V4L2_EVENT_FRAME_END &&
183 	    sub->type != V4L2_EVENT_ATOMISP_3A_STATS_READY &&
184 	    sub->type != V4L2_EVENT_ATOMISP_METADATA_READY &&
185 	    sub->type != V4L2_EVENT_ATOMISP_PAUSE_BUFFER &&
186 	    sub->type != V4L2_EVENT_ATOMISP_CSS_RESET &&
187 	    sub->type != V4L2_EVENT_ATOMISP_RAW_BUFFERS_ALLOC_DONE &&
188 	    sub->type != V4L2_EVENT_ATOMISP_ACC_COMPLETE)
189 		return -EINVAL;
190 
191 	if (sub->type == V4L2_EVENT_FRAME_SYNC &&
192 	    !atomisp_css_valid_sof(isp))
193 		return -EINVAL;
194 
195 	return v4l2_event_subscribe(fh, sub, 16, NULL);
196 }
197 
198 static int isp_subdev_unsubscribe_event(struct v4l2_subdev *sd,
199 					struct v4l2_fh *fh,
200 					struct v4l2_event_subscription *sub)
201 {
202 	return v4l2_event_unsubscribe(fh, sub);
203 }
204 
205 /*
206  * isp_subdev_enum_mbus_code - Handle pixel format enumeration
207  * @sd: pointer to v4l2 subdev structure
208  * @fh : V4L2 subdev file handle
209  * @code: pointer to v4l2_subdev_pad_mbus_code_enum structure
210  * return -EINVAL or zero on success
211  */
212 static int isp_subdev_enum_mbus_code(struct v4l2_subdev *sd,
213 				     struct v4l2_subdev_pad_config *cfg,
214 				     struct v4l2_subdev_mbus_code_enum *code)
215 {
216 	if (code->index >= ARRAY_SIZE(atomisp_in_fmt_conv) - 1)
217 		return -EINVAL;
218 
219 	code->code = atomisp_in_fmt_conv[code->index].code;
220 
221 	return 0;
222 }
223 
224 static int isp_subdev_validate_rect(struct v4l2_subdev *sd, uint32_t pad,
225 				    uint32_t target)
226 {
227 	switch (pad) {
228 	case ATOMISP_SUBDEV_PAD_SINK:
229 		switch (target) {
230 		case V4L2_SEL_TGT_CROP:
231 			return 0;
232 		}
233 		break;
234 	default:
235 		switch (target) {
236 		case V4L2_SEL_TGT_COMPOSE:
237 			return 0;
238 		}
239 		break;
240 	}
241 
242 	return -EINVAL;
243 }
244 
245 struct v4l2_rect *atomisp_subdev_get_rect(struct v4l2_subdev *sd,
246 	struct v4l2_subdev_pad_config *cfg,
247 	u32 which, uint32_t pad,
248 	uint32_t target)
249 {
250 	struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd);
251 
252 	if (which == V4L2_SUBDEV_FORMAT_TRY) {
253 		switch (target) {
254 		case V4L2_SEL_TGT_CROP:
255 			return v4l2_subdev_get_try_crop(sd, cfg, pad);
256 		case V4L2_SEL_TGT_COMPOSE:
257 			return v4l2_subdev_get_try_compose(sd, cfg, pad);
258 		}
259 	}
260 
261 	switch (target) {
262 	case V4L2_SEL_TGT_CROP:
263 		return &isp_sd->fmt[pad].crop;
264 	case V4L2_SEL_TGT_COMPOSE:
265 		return &isp_sd->fmt[pad].compose;
266 	}
267 
268 	return NULL;
269 }
270 
271 struct v4l2_mbus_framefmt
272 *atomisp_subdev_get_ffmt(struct v4l2_subdev *sd,
273 			 struct v4l2_subdev_pad_config *cfg, uint32_t which,
274 			 uint32_t pad)
275 {
276 	struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd);
277 
278 	if (which == V4L2_SUBDEV_FORMAT_TRY)
279 		return v4l2_subdev_get_try_format(sd, cfg, pad);
280 
281 	return &isp_sd->fmt[pad].fmt;
282 }
283 
284 static void isp_get_fmt_rect(struct v4l2_subdev *sd,
285 			     struct v4l2_subdev_pad_config *cfg, uint32_t which,
286 			     struct v4l2_mbus_framefmt **ffmt,
287 			     struct v4l2_rect *crop[ATOMISP_SUBDEV_PADS_NUM],
288 			     struct v4l2_rect *comp[ATOMISP_SUBDEV_PADS_NUM])
289 {
290 	unsigned int i;
291 
292 	for (i = 0; i < ATOMISP_SUBDEV_PADS_NUM; i++) {
293 		ffmt[i] = atomisp_subdev_get_ffmt(sd, cfg, which, i);
294 		crop[i] = atomisp_subdev_get_rect(sd, cfg, which, i,
295 						  V4L2_SEL_TGT_CROP);
296 		comp[i] = atomisp_subdev_get_rect(sd, cfg, which, i,
297 						  V4L2_SEL_TGT_COMPOSE);
298 	}
299 }
300 
301 static void isp_subdev_propagate(struct v4l2_subdev *sd,
302 				 struct v4l2_subdev_pad_config *cfg,
303 				 u32 which, uint32_t pad, uint32_t target,
304 				 uint32_t flags)
305 {
306 	struct v4l2_mbus_framefmt *ffmt[ATOMISP_SUBDEV_PADS_NUM];
307 	struct v4l2_rect *crop[ATOMISP_SUBDEV_PADS_NUM],
308 		       *comp[ATOMISP_SUBDEV_PADS_NUM];
309 
310 	if (flags & V4L2_SEL_FLAG_KEEP_CONFIG)
311 		return;
312 
313 	isp_get_fmt_rect(sd, cfg, which, ffmt, crop, comp);
314 
315 	switch (pad) {
316 	case ATOMISP_SUBDEV_PAD_SINK: {
317 		struct v4l2_rect r = {0};
318 
319 		/* Only crop target supported on sink pad. */
320 		r.width = ffmt[pad]->width;
321 		r.height = ffmt[pad]->height;
322 
323 		atomisp_subdev_set_selection(sd, cfg, which, pad,
324 					     target, flags, &r);
325 		break;
326 	}
327 	}
328 }
329 
330 static int isp_subdev_get_selection(struct v4l2_subdev *sd,
331 				    struct v4l2_subdev_pad_config *cfg,
332 				    struct v4l2_subdev_selection *sel)
333 {
334 	struct v4l2_rect *rec;
335 	int rval = isp_subdev_validate_rect(sd, sel->pad, sel->target);
336 
337 	if (rval)
338 		return rval;
339 
340 	rec = atomisp_subdev_get_rect(sd, cfg, sel->which, sel->pad,
341 				      sel->target);
342 	if (!rec)
343 		return -EINVAL;
344 
345 	sel->r = *rec;
346 	return 0;
347 }
348 
349 static char *atomisp_pad_str[] = { "ATOMISP_SUBDEV_PAD_SINK",
350 				   "ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE",
351 				   "ATOMISP_SUBDEV_PAD_SOURCE_VF",
352 				   "ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW",
353 				   "ATOMISP_SUBDEV_PAD_SOURCE_VIDEO"
354 				 };
355 
356 int atomisp_subdev_set_selection(struct v4l2_subdev *sd,
357 				 struct v4l2_subdev_pad_config *cfg,
358 				 u32 which, uint32_t pad, uint32_t target,
359 				 u32 flags, struct v4l2_rect *r)
360 {
361 	struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd);
362 	struct atomisp_device *isp = isp_sd->isp;
363 	struct v4l2_mbus_framefmt *ffmt[ATOMISP_SUBDEV_PADS_NUM];
364 	u16 vdev_pad = atomisp_subdev_source_pad(sd->devnode);
365 	struct v4l2_rect *crop[ATOMISP_SUBDEV_PADS_NUM],
366 		       *comp[ATOMISP_SUBDEV_PADS_NUM];
367 	enum atomisp_input_stream_id stream_id;
368 	unsigned int i;
369 	unsigned int padding_w = pad_w;
370 	unsigned int padding_h = pad_h;
371 
372 	stream_id = atomisp_source_pad_to_stream_id(isp_sd, vdev_pad);
373 
374 	isp_get_fmt_rect(sd, cfg, which, ffmt, crop, comp);
375 
376 	dev_dbg(isp->dev,
377 		"sel: pad %s tgt %s l %d t %d w %d h %d which %s f 0x%8.8x\n",
378 		atomisp_pad_str[pad], target == V4L2_SEL_TGT_CROP
379 		? "V4L2_SEL_TGT_CROP" : "V4L2_SEL_TGT_COMPOSE",
380 		r->left, r->top, r->width, r->height,
381 		which == V4L2_SUBDEV_FORMAT_TRY ? "V4L2_SUBDEV_FORMAT_TRY"
382 		: "V4L2_SUBDEV_FORMAT_ACTIVE", flags);
383 
384 	r->width = rounddown(r->width, ATOM_ISP_STEP_WIDTH);
385 	r->height = rounddown(r->height, ATOM_ISP_STEP_HEIGHT);
386 
387 	switch (pad) {
388 	case ATOMISP_SUBDEV_PAD_SINK: {
389 		/* Only crop target supported on sink pad. */
390 		unsigned int dvs_w, dvs_h;
391 
392 		crop[pad]->width = ffmt[pad]->width;
393 		crop[pad]->height = ffmt[pad]->height;
394 
395 		/* Workaround for BYT 1080p perfectshot since the maxinum resolution of
396 		 * front camera ov2722 is 1932x1092 and cannot use pad_w > 12*/
397 		if (!strncmp(isp->inputs[isp_sd->input_curr].camera->name,
398 			     "ov2722", 6) && crop[pad]->height == 1092) {
399 			padding_w = 12;
400 			padding_h = 12;
401 		}
402 
403 		if (isp->inputs[isp_sd->input_curr].type == SOC_CAMERA) {
404 			padding_w = 0;
405 			padding_h = 0;
406 		}
407 
408 		if (atomisp_subdev_format_conversion(isp_sd,
409 						     isp_sd->capture_pad)
410 		    && crop[pad]->width && crop[pad]->height)
411 			crop[pad]->width -= padding_w, crop[pad]->height -= padding_h;
412 
413 		/* if subdev type is SOC camera,we do not need to set DVS */
414 		if (isp->inputs[isp_sd->input_curr].type == SOC_CAMERA)
415 			isp_sd->params.video_dis_en = 0;
416 
417 		if (isp_sd->params.video_dis_en &&
418 		    isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO &&
419 		    !isp_sd->continuous_mode->val) {
420 			/* This resolution contains 20 % of DVS slack
421 			 * (of the desired captured image before
422 			 * scaling, or 1 / 6 of what we get from the
423 			 * sensor) in both width and height. Remove
424 			 * it. */
425 			crop[pad]->width = roundup(crop[pad]->width * 5 / 6,
426 						   ATOM_ISP_STEP_WIDTH);
427 			crop[pad]->height = roundup(crop[pad]->height * 5 / 6,
428 						    ATOM_ISP_STEP_HEIGHT);
429 		}
430 
431 		crop[pad]->width = min(crop[pad]->width, r->width);
432 		crop[pad]->height = min(crop[pad]->height, r->height);
433 
434 		if (!(flags & V4L2_SEL_FLAG_KEEP_CONFIG)) {
435 			for (i = ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE;
436 			     i < ATOMISP_SUBDEV_PADS_NUM; i++) {
437 				struct v4l2_rect tmp = *crop[pad];
438 
439 				atomisp_subdev_set_selection(
440 				    sd, cfg, which, i, V4L2_SEL_TGT_COMPOSE,
441 				    flags, &tmp);
442 			}
443 		}
444 
445 		if (which == V4L2_SUBDEV_FORMAT_TRY)
446 			break;
447 
448 		if (isp_sd->params.video_dis_en &&
449 		    isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO &&
450 		    !isp_sd->continuous_mode->val) {
451 			dvs_w = rounddown(crop[pad]->width / 5,
452 					  ATOM_ISP_STEP_WIDTH);
453 			dvs_h = rounddown(crop[pad]->height / 5,
454 					  ATOM_ISP_STEP_HEIGHT);
455 		} else if (!isp_sd->params.video_dis_en &&
456 			   isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
457 			/*
458 			 * For CSS2.0, digital zoom needs to set dvs envelope to 12
459 			 * when dvs is disabled.
460 			 */
461 			dvs_w = dvs_h = 12;
462 		} else
463 			dvs_w = dvs_h = 0;
464 
465 		atomisp_css_video_set_dis_envelope(isp_sd, dvs_w, dvs_h);
466 		atomisp_css_input_set_effective_resolution(isp_sd, stream_id,
467 			crop[pad]->width, crop[pad]->height);
468 
469 		break;
470 	}
471 	case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE:
472 	case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO: {
473 		/* Only compose target is supported on source pads. */
474 
475 		if (isp_sd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) {
476 			/* Scaling is disabled in this mode */
477 			r->width = crop[ATOMISP_SUBDEV_PAD_SINK]->width;
478 			r->height = crop[ATOMISP_SUBDEV_PAD_SINK]->height;
479 		}
480 
481 		if (crop[ATOMISP_SUBDEV_PAD_SINK]->width == r->width
482 		    && crop[ATOMISP_SUBDEV_PAD_SINK]->height == r->height)
483 			isp_sd->params.yuv_ds_en = false;
484 		else
485 			isp_sd->params.yuv_ds_en = true;
486 
487 		comp[pad]->width = r->width;
488 		comp[pad]->height = r->height;
489 
490 		if (r->width == 0 || r->height == 0 ||
491 		    crop[ATOMISP_SUBDEV_PAD_SINK]->width == 0 ||
492 		    crop[ATOMISP_SUBDEV_PAD_SINK]->height == 0)
493 			break;
494 		/*
495 		 * do cropping on sensor input if ratio of required resolution
496 		 * is different with sensor output resolution ratio:
497 		 *
498 		 * ratio = width / height
499 		 *
500 		 * if ratio_output < ratio_sensor:
501 		 *	effect_width = sensor_height * out_width / out_height;
502 		 *	effect_height = sensor_height;
503 		 * else
504 		 *	effect_width = sensor_width;
505 		 *	effect_height = sensor_width * out_height / out_width;
506 		 *
507 		 */
508 		if (r->width * crop[ATOMISP_SUBDEV_PAD_SINK]->height <
509 		    crop[ATOMISP_SUBDEV_PAD_SINK]->width * r->height)
510 			atomisp_css_input_set_effective_resolution(isp_sd,
511 				stream_id,
512 				rounddown(crop[ATOMISP_SUBDEV_PAD_SINK]->
513 					  height * r->width / r->height,
514 					  ATOM_ISP_STEP_WIDTH),
515 				crop[ATOMISP_SUBDEV_PAD_SINK]->height);
516 		else
517 			atomisp_css_input_set_effective_resolution(isp_sd,
518 				stream_id,
519 				crop[ATOMISP_SUBDEV_PAD_SINK]->width,
520 				rounddown(crop[ATOMISP_SUBDEV_PAD_SINK]->
521 					  width * r->height / r->width,
522 					  ATOM_ISP_STEP_WIDTH));
523 
524 		break;
525 	}
526 	case ATOMISP_SUBDEV_PAD_SOURCE_VF:
527 	case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW:
528 		comp[pad]->width = r->width;
529 		comp[pad]->height = r->height;
530 		break;
531 	default:
532 		return -EINVAL;
533 	}
534 
535 	/* Set format dimensions on non-sink pads as well. */
536 	if (pad != ATOMISP_SUBDEV_PAD_SINK) {
537 		ffmt[pad]->width = comp[pad]->width;
538 		ffmt[pad]->height = comp[pad]->height;
539 	}
540 
541 	if (!atomisp_subdev_get_rect(sd, cfg, which, pad, target))
542 		return -EINVAL;
543 	*r = *atomisp_subdev_get_rect(sd, cfg, which, pad, target);
544 
545 	dev_dbg(isp->dev, "sel actual: l %d t %d w %d h %d\n",
546 		r->left, r->top, r->width, r->height);
547 
548 	return 0;
549 }
550 
551 static int isp_subdev_set_selection(struct v4l2_subdev *sd,
552 				    struct v4l2_subdev_pad_config *cfg,
553 				    struct v4l2_subdev_selection *sel)
554 {
555 	int rval = isp_subdev_validate_rect(sd, sel->pad, sel->target);
556 
557 	if (rval)
558 		return rval;
559 
560 	return atomisp_subdev_set_selection(sd, cfg, sel->which, sel->pad,
561 					    sel->target, sel->flags, &sel->r);
562 }
563 
564 static int atomisp_get_sensor_bin_factor(struct atomisp_sub_device *asd)
565 {
566 	struct v4l2_control ctrl = {0};
567 	struct atomisp_device *isp = asd->isp;
568 	int hbin, vbin;
569 	int ret;
570 
571 	if (isp->inputs[asd->input_curr].type == FILE_INPUT ||
572 	    isp->inputs[asd->input_curr].type == TEST_PATTERN)
573 		return 0;
574 
575 	ctrl.id = V4L2_CID_BIN_FACTOR_HORZ;
576 	ret =
577 	    v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->ctrl_handler,
578 			&ctrl);
579 	hbin = ctrl.value;
580 	ctrl.id = V4L2_CID_BIN_FACTOR_VERT;
581 	ret |=
582 	    v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->ctrl_handler,
583 			&ctrl);
584 	vbin = ctrl.value;
585 
586 	/*
587 	 * ISP needs to know binning factor from sensor.
588 	 * In case horizontal and vertical sensor's binning factors
589 	 * are different or sensor does not support binning factor CID,
590 	 * ISP will apply default 0 value.
591 	 */
592 	if (ret || hbin != vbin)
593 		hbin = 0;
594 
595 	return hbin;
596 }
597 
598 void atomisp_subdev_set_ffmt(struct v4l2_subdev *sd,
599 			     struct v4l2_subdev_pad_config *cfg, uint32_t which,
600 			     u32 pad, struct v4l2_mbus_framefmt *ffmt)
601 {
602 	struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd);
603 	struct atomisp_device *isp = isp_sd->isp;
604 	struct v4l2_mbus_framefmt *__ffmt =
605 	    atomisp_subdev_get_ffmt(sd, cfg, which, pad);
606 	u16 vdev_pad = atomisp_subdev_source_pad(sd->devnode);
607 	enum atomisp_input_stream_id stream_id;
608 
609 	dev_dbg(isp->dev, "ffmt: pad %s w %d h %d code 0x%8.8x which %s\n",
610 		atomisp_pad_str[pad], ffmt->width, ffmt->height, ffmt->code,
611 		which == V4L2_SUBDEV_FORMAT_TRY ? "V4L2_SUBDEV_FORMAT_TRY"
612 		: "V4L2_SUBDEV_FORMAT_ACTIVE");
613 
614 	stream_id = atomisp_source_pad_to_stream_id(isp_sd, vdev_pad);
615 
616 	switch (pad) {
617 	case ATOMISP_SUBDEV_PAD_SINK: {
618 		const struct atomisp_in_fmt_conv *fc =
619 		    atomisp_find_in_fmt_conv(ffmt->code);
620 
621 		if (!fc) {
622 			fc = atomisp_in_fmt_conv;
623 			ffmt->code = fc->code;
624 			dev_dbg(isp->dev, "using 0x%8.8x instead\n",
625 				ffmt->code);
626 		}
627 
628 		*__ffmt = *ffmt;
629 
630 		isp_subdev_propagate(sd, cfg, which, pad,
631 				     V4L2_SEL_TGT_CROP, 0);
632 
633 		if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
634 			atomisp_css_input_set_resolution(isp_sd,
635 							 stream_id, ffmt);
636 			atomisp_css_input_set_binning_factor(isp_sd,
637 							     stream_id,
638 							     atomisp_get_sensor_bin_factor(isp_sd));
639 			atomisp_css_input_set_bayer_order(isp_sd, stream_id,
640 							  fc->bayer_order);
641 			atomisp_css_input_set_format(isp_sd, stream_id,
642 						     fc->css_stream_fmt);
643 			atomisp_css_set_default_isys_config(isp_sd, stream_id,
644 							    ffmt);
645 		}
646 
647 		break;
648 	}
649 	case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE:
650 	case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW:
651 	case ATOMISP_SUBDEV_PAD_SOURCE_VF:
652 	case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO:
653 		__ffmt->code = ffmt->code;
654 		break;
655 	}
656 }
657 
658 /*
659  * isp_subdev_get_format - Retrieve the video format on a pad
660  * @sd : ISP V4L2 subdevice
661  * @fh : V4L2 subdev file handle
662  * @pad: Pad number
663  * @fmt: Format
664  *
665  * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
666  * to the format type.
667  */
668 static int isp_subdev_get_format(struct v4l2_subdev *sd,
669 				 struct v4l2_subdev_pad_config *cfg,
670 				 struct v4l2_subdev_format *fmt)
671 {
672 	fmt->format = *atomisp_subdev_get_ffmt(sd, cfg, fmt->which, fmt->pad);
673 
674 	return 0;
675 }
676 
677 /*
678  * isp_subdev_set_format - Set the video format on a pad
679  * @sd : ISP subdev V4L2 subdevice
680  * @fh : V4L2 subdev file handle
681  * @pad: Pad number
682  * @fmt: Format
683  *
684  * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
685  * to the format type.
686  */
687 static int isp_subdev_set_format(struct v4l2_subdev *sd,
688 				 struct v4l2_subdev_pad_config *cfg,
689 				 struct v4l2_subdev_format *fmt)
690 {
691 	atomisp_subdev_set_ffmt(sd, cfg, fmt->which, fmt->pad, &fmt->format);
692 
693 	return 0;
694 }
695 
696 /* V4L2 subdev core operations */
697 static const struct v4l2_subdev_core_ops isp_subdev_v4l2_core_ops = {
698 	.ioctl = isp_subdev_ioctl, .s_power = isp_subdev_set_power,
699 	.subscribe_event = isp_subdev_subscribe_event,
700 	.unsubscribe_event = isp_subdev_unsubscribe_event,
701 };
702 
703 /* V4L2 subdev pad operations */
704 static const struct v4l2_subdev_pad_ops isp_subdev_v4l2_pad_ops = {
705 	.enum_mbus_code = isp_subdev_enum_mbus_code,
706 	.get_fmt = isp_subdev_get_format,
707 	.set_fmt = isp_subdev_set_format,
708 	.get_selection = isp_subdev_get_selection,
709 	.set_selection = isp_subdev_set_selection,
710 	.link_validate = v4l2_subdev_link_validate_default,
711 };
712 
713 /* V4L2 subdev operations */
714 static const struct v4l2_subdev_ops isp_subdev_v4l2_ops = {
715 	.core = &isp_subdev_v4l2_core_ops,
716 	.pad = &isp_subdev_v4l2_pad_ops,
717 };
718 
719 static void isp_subdev_init_params(struct atomisp_sub_device *asd)
720 {
721 	unsigned int i;
722 
723 	/* parameters initialization */
724 	INIT_LIST_HEAD(&asd->s3a_stats);
725 	INIT_LIST_HEAD(&asd->s3a_stats_in_css);
726 	INIT_LIST_HEAD(&asd->s3a_stats_ready);
727 	INIT_LIST_HEAD(&asd->dis_stats);
728 	INIT_LIST_HEAD(&asd->dis_stats_in_css);
729 	spin_lock_init(&asd->dis_stats_lock);
730 	for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
731 		INIT_LIST_HEAD(&asd->metadata[i]);
732 		INIT_LIST_HEAD(&asd->metadata_in_css[i]);
733 		INIT_LIST_HEAD(&asd->metadata_ready[i]);
734 	}
735 }
736 
737 /*
738 * isp_subdev_link_setup - Setup isp subdev connections
739 * @entity: ispsubdev media entity
740 * @local: Pad at the local end of the link
741 * @remote: Pad at the remote end of the link
742 * @flags: Link flags
743 *
744 * return -EINVAL or zero on success
745 */
746 static int isp_subdev_link_setup(struct media_entity *entity,
747 				 const struct media_pad *local,
748 				 const struct media_pad *remote, u32 flags)
749 {
750 	struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
751 	struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd);
752 	struct atomisp_device *isp = isp_sd->isp;
753 	unsigned int i;
754 
755 	switch (local->index | is_media_entity_v4l2_subdev(remote->entity)) {
756 	case ATOMISP_SUBDEV_PAD_SINK | MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN:
757 		/* Read from the sensor CSI2-ports. */
758 		if (!(flags & MEDIA_LNK_FL_ENABLED)) {
759 			isp_sd->input = ATOMISP_SUBDEV_INPUT_NONE;
760 			break;
761 		}
762 
763 		if (isp_sd->input != ATOMISP_SUBDEV_INPUT_NONE)
764 			return -EBUSY;
765 
766 		for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) {
767 			if (remote->entity != &isp->csi2_port[i].subdev.entity)
768 				continue;
769 
770 			isp_sd->input = ATOMISP_SUBDEV_INPUT_CSI2_PORT1 + i;
771 			return 0;
772 		}
773 
774 		return -EINVAL;
775 
776 	case ATOMISP_SUBDEV_PAD_SINK | MEDIA_ENT_F_OLD_BASE:
777 		/* read from memory */
778 		if (flags & MEDIA_LNK_FL_ENABLED) {
779 			if (isp_sd->input >= ATOMISP_SUBDEV_INPUT_CSI2_PORT1 &&
780 			    isp_sd->input < (ATOMISP_SUBDEV_INPUT_CSI2_PORT1
781 					     + ATOMISP_CAMERA_NR_PORTS))
782 				return -EBUSY;
783 			isp_sd->input = ATOMISP_SUBDEV_INPUT_MEMORY;
784 		} else {
785 			if (isp_sd->input == ATOMISP_SUBDEV_INPUT_MEMORY)
786 				isp_sd->input = ATOMISP_SUBDEV_INPUT_NONE;
787 		}
788 		break;
789 
790 	case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW | MEDIA_ENT_F_OLD_BASE:
791 		/* always write to memory */
792 		break;
793 
794 	case ATOMISP_SUBDEV_PAD_SOURCE_VF | MEDIA_ENT_F_OLD_BASE:
795 		/* always write to memory */
796 		break;
797 
798 	case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE | MEDIA_ENT_F_OLD_BASE:
799 		/* always write to memory */
800 		break;
801 
802 	case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO | MEDIA_ENT_F_OLD_BASE:
803 		/* always write to memory */
804 		break;
805 
806 	default:
807 		return -EINVAL;
808 	}
809 
810 	return 0;
811 }
812 
813 /* media operations */
814 static const struct media_entity_operations isp_subdev_media_ops = {
815 	.link_setup = isp_subdev_link_setup,
816 	.link_validate = v4l2_subdev_link_validate,
817 	/*	 .set_power = v4l2_subdev_set_power,	*/
818 };
819 
820 static int __atomisp_update_run_mode(struct atomisp_sub_device *asd)
821 {
822 	struct atomisp_device *isp = asd->isp;
823 	struct v4l2_ctrl *ctrl = asd->run_mode;
824 	struct v4l2_ctrl *c;
825 	s32 mode;
826 
827 	if (ctrl->val != ATOMISP_RUN_MODE_VIDEO &&
828 	    asd->continuous_mode->val)
829 		mode = ATOMISP_RUN_MODE_PREVIEW;
830 	else
831 		mode = ctrl->val;
832 
833 	c = v4l2_ctrl_find(
834 		isp->inputs[asd->input_curr].camera->ctrl_handler,
835 		V4L2_CID_RUN_MODE);
836 
837 	if (c)
838 		return v4l2_ctrl_s_ctrl(c, mode);
839 
840 	return 0;
841 }
842 
843 int atomisp_update_run_mode(struct atomisp_sub_device *asd)
844 {
845 	int rval;
846 
847 	mutex_lock(asd->ctrl_handler.lock);
848 	rval = __atomisp_update_run_mode(asd);
849 	mutex_unlock(asd->ctrl_handler.lock);
850 
851 	return rval;
852 }
853 
854 static int s_ctrl(struct v4l2_ctrl *ctrl)
855 {
856 	struct atomisp_sub_device *asd = container_of(
857 					     ctrl->handler, struct atomisp_sub_device, ctrl_handler);
858 
859 	switch (ctrl->id) {
860 	case V4L2_CID_RUN_MODE:
861 		return __atomisp_update_run_mode(asd);
862 	case V4L2_CID_DEPTH_MODE:
863 		if (asd->streaming != ATOMISP_DEVICE_STREAMING_DISABLED) {
864 			dev_err(asd->isp->dev,
865 				"ISP is streaming, it is not supported to change the depth mode\n");
866 			return -EINVAL;
867 		}
868 		break;
869 	}
870 
871 	return 0;
872 }
873 
874 static const struct v4l2_ctrl_ops ctrl_ops = {
875 	.s_ctrl = &s_ctrl,
876 };
877 
878 static const struct v4l2_ctrl_config ctrl_fmt_auto = {
879 	.ops = &ctrl_ops,
880 	.id = V4L2_CID_FMT_AUTO,
881 	.name = "Automatic format guessing",
882 	.type = V4L2_CTRL_TYPE_BOOLEAN,
883 	.min = 0,
884 	.max = 1,
885 	.step = 1,
886 	.def = 1,
887 };
888 
889 static const char *const ctrl_run_mode_menu[] = {
890 	NULL,
891 	"Video",
892 	"Still capture",
893 	"Continuous capture",
894 	"Preview",
895 };
896 
897 static const struct v4l2_ctrl_config ctrl_run_mode = {
898 	.ops = &ctrl_ops,
899 	.id = V4L2_CID_RUN_MODE,
900 	.name = "Atomisp run mode",
901 	.type = V4L2_CTRL_TYPE_MENU,
902 	.min = 1,
903 	.def = 1,
904 	.max = 4,
905 	.qmenu = ctrl_run_mode_menu,
906 };
907 
908 static const char *const ctrl_vfpp_mode_menu[] = {
909 	"Enable",			/* vfpp always enabled */
910 	"Disable to scaler mode",	/* CSS into video mode and disable */
911 	"Disable to low latency mode",	/* CSS into still mode and disable */
912 };
913 
914 static const struct v4l2_ctrl_config ctrl_vfpp = {
915 	.id = V4L2_CID_VFPP,
916 	.name = "Atomisp vf postprocess",
917 	.type = V4L2_CTRL_TYPE_MENU,
918 	.min = 0,
919 	.def = 0,
920 	.max = 2,
921 	.qmenu = ctrl_vfpp_mode_menu,
922 };
923 
924 /*
925  * Control for ISP continuous mode
926  *
927  * When enabled, capture processing is possible without
928  * stopping the preview pipeline. When disabled, ISP needs
929  * to be restarted between preview and capture.
930  */
931 static const struct v4l2_ctrl_config ctrl_continuous_mode = {
932 	.ops = &ctrl_ops,
933 	.id = V4L2_CID_ATOMISP_CONTINUOUS_MODE,
934 	.type = V4L2_CTRL_TYPE_BOOLEAN,
935 	.name = "Continuous mode",
936 	.min = 0,
937 	.max = 1,
938 	.step = 1,
939 	.def = 0,
940 };
941 
942 /*
943  * Control for continuous mode raw buffer size
944  *
945  * The size of the RAW ringbuffer sets limit on how much
946  * back in time application can go when requesting capture
947  * frames to be rendered, and how many frames can be rendered
948  * in a burst at full sensor rate.
949  *
950  * Note: this setting has a big impact on memory consumption of
951  * the CSS subsystem.
952  */
953 static const struct v4l2_ctrl_config ctrl_continuous_raw_buffer_size = {
954 	.ops = &ctrl_ops,
955 	.id = V4L2_CID_ATOMISP_CONTINUOUS_RAW_BUFFER_SIZE,
956 	.type = V4L2_CTRL_TYPE_INTEGER,
957 	.name = "Continuous raw ringbuffer size",
958 	.min = 1,
959 	.max = 100, /* depends on CSS version, runtime checked */
960 	.step = 1,
961 	.def = 3,
962 };
963 
964 /*
965  * Control for enabling continuous viewfinder
966  *
967  * When enabled, and ISP is in continuous mode (see ctrl_continuous_mode ),
968  * preview pipeline continues concurrently with capture
969  * processing. When disabled, and continuous mode is used,
970  * preview is paused while captures are processed, but
971  * full pipeline restart is not needed.
972  *
973  * By setting this to disabled, capture processing is
974  * essentially given priority over preview, and the effective
975  * capture output rate may be higher than with continuous
976  * viewfinder enabled.
977  */
978 static const struct v4l2_ctrl_config ctrl_continuous_viewfinder = {
979 	.id = V4L2_CID_ATOMISP_CONTINUOUS_VIEWFINDER,
980 	.type = V4L2_CTRL_TYPE_BOOLEAN,
981 	.name = "Continuous viewfinder",
982 	.min = 0,
983 	.max = 1,
984 	.step = 1,
985 	.def = 0,
986 };
987 
988 /*
989  * Control for enabling Lock&Unlock Raw Buffer mechanism
990  *
991  * When enabled, Raw Buffer can be locked and unlocked.
992  * Application can hold the exp_id of Raw Buffer
993  * and unlock it when no longer needed.
994  * Note: Make sure set this configuration before creating stream.
995  */
996 static const struct v4l2_ctrl_config ctrl_enable_raw_buffer_lock = {
997 	.id = V4L2_CID_ENABLE_RAW_BUFFER_LOCK,
998 	.type = V4L2_CTRL_TYPE_BOOLEAN,
999 	.name = "Lock Unlock Raw Buffer",
1000 	.min = 0,
1001 	.max = 1,
1002 	.step = 1,
1003 	.def = 0,
1004 };
1005 
1006 /*
1007  * Control to disable digital zoom of the whole stream
1008  *
1009  * When it is true, pipe configuration enable_dz will be set to false.
1010  * This can help get a better performance by disabling pp binary.
1011  *
1012  * Note: Make sure set this configuration before creating stream.
1013  */
1014 static const struct v4l2_ctrl_config ctrl_disable_dz = {
1015 	.id = V4L2_CID_DISABLE_DZ,
1016 	.type = V4L2_CTRL_TYPE_BOOLEAN,
1017 	.name = "Disable digital zoom",
1018 	.min = 0,
1019 	.max = 1,
1020 	.step = 1,
1021 	.def = 0,
1022 };
1023 
1024 /*
1025  * Control for ISP depth mode
1026  *
1027  * When enabled, that means ISP will deal with dual streams and sensors will be
1028  * in slave/master mode.
1029  * slave sensor will have no output until master sensor is streamed on.
1030  */
1031 static const struct v4l2_ctrl_config ctrl_depth_mode = {
1032 	.ops = &ctrl_ops,
1033 	.id = V4L2_CID_DEPTH_MODE,
1034 	.type = V4L2_CTRL_TYPE_BOOLEAN,
1035 	.name = "Depth mode",
1036 	.min = 0,
1037 	.max = 1,
1038 	.step = 1,
1039 	.def = 0,
1040 };
1041 
1042 /*
1043  * Control for selectting ISP version
1044  *
1045  * When enabled, that means ISP version will be used ISP2.7. when disable, the
1046  * isp will default to use ISP2.2.
1047  * Note: Make sure set this configuration before creating stream.
1048  */
1049 static const struct v4l2_ctrl_config ctrl_select_isp_version = {
1050 	.ops = &ctrl_ops,
1051 	.id = V4L2_CID_ATOMISP_SELECT_ISP_VERSION,
1052 	.type = V4L2_CTRL_TYPE_BOOLEAN,
1053 	.name = "Select Isp version",
1054 	.min = 0,
1055 	.max = 1,
1056 	.step = 1,
1057 	.def = 0,
1058 };
1059 
1060 #if 0 /* #ifdef CONFIG_ION */
1061 /*
1062  * Control for ISP ion device fd
1063  *
1064  * userspace will open ion device and pass the fd to kernel.
1065  * this fd will be used to map shared fd to buffer.
1066  */
1067 /* V4L2_CID_ATOMISP_ION_DEVICE_FD is not defined */
1068 static const struct v4l2_ctrl_config ctrl_ion_dev_fd = {
1069 	.ops = &ctrl_ops,
1070 	.id = V4L2_CID_ATOMISP_ION_DEVICE_FD,
1071 	.type = V4L2_CTRL_TYPE_INTEGER,
1072 	.name = "Ion Device Fd",
1073 	.min = -1,
1074 	.max = 1024,
1075 	.step = 1,
1076 	.def = ION_FD_UNSET
1077 };
1078 #endif
1079 
1080 static void atomisp_init_subdev_pipe(struct atomisp_sub_device *asd,
1081 				     struct atomisp_video_pipe *pipe, enum v4l2_buf_type buf_type)
1082 {
1083 	pipe->type = buf_type;
1084 	pipe->asd = asd;
1085 	pipe->isp = asd->isp;
1086 	spin_lock_init(&pipe->irq_lock);
1087 	INIT_LIST_HEAD(&pipe->activeq);
1088 	INIT_LIST_HEAD(&pipe->activeq_out);
1089 	INIT_LIST_HEAD(&pipe->buffers_waiting_for_param);
1090 	INIT_LIST_HEAD(&pipe->per_frame_params);
1091 	memset(pipe->frame_request_config_id,
1092 	       0, VIDEO_MAX_FRAME * sizeof(unsigned int));
1093 	memset(pipe->frame_params,
1094 	       0, VIDEO_MAX_FRAME *
1095 	       sizeof(struct atomisp_css_params_with_list *));
1096 }
1097 
1098 static void atomisp_init_acc_pipe(struct atomisp_sub_device *asd,
1099 				  struct atomisp_acc_pipe *pipe)
1100 {
1101 	pipe->asd = asd;
1102 	pipe->isp = asd->isp;
1103 	INIT_LIST_HEAD(&asd->acc.fw);
1104 	INIT_LIST_HEAD(&asd->acc.memory_maps);
1105 	ida_init(&asd->acc.ida);
1106 }
1107 
1108 /*
1109  * isp_subdev_init_entities - Initialize V4L2 subdev and media entity
1110  * @asd: ISP CCDC module
1111  *
1112  * Return 0 on success and a negative error code on failure.
1113  */
1114 static int isp_subdev_init_entities(struct atomisp_sub_device *asd)
1115 {
1116 	struct v4l2_subdev *sd = &asd->subdev;
1117 	struct media_pad *pads = asd->pads;
1118 	struct media_entity *me = &sd->entity;
1119 	int ret;
1120 
1121 	asd->input = ATOMISP_SUBDEV_INPUT_NONE;
1122 
1123 	v4l2_subdev_init(sd, &isp_subdev_v4l2_ops);
1124 	sprintf(sd->name, "ATOMISP_SUBDEV_%d", asd->index);
1125 	v4l2_set_subdevdata(sd, asd);
1126 	sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1127 
1128 	pads[ATOMISP_SUBDEV_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1129 	pads[ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW].flags = MEDIA_PAD_FL_SOURCE;
1130 	pads[ATOMISP_SUBDEV_PAD_SOURCE_VF].flags = MEDIA_PAD_FL_SOURCE;
1131 	pads[ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE].flags = MEDIA_PAD_FL_SOURCE;
1132 	pads[ATOMISP_SUBDEV_PAD_SOURCE_VIDEO].flags = MEDIA_PAD_FL_SOURCE;
1133 
1134 	asd->fmt[ATOMISP_SUBDEV_PAD_SINK].fmt.code =
1135 	    MEDIA_BUS_FMT_SBGGR10_1X10;
1136 	asd->fmt[ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW].fmt.code =
1137 	    MEDIA_BUS_FMT_SBGGR10_1X10;
1138 	asd->fmt[ATOMISP_SUBDEV_PAD_SOURCE_VF].fmt.code =
1139 	    MEDIA_BUS_FMT_SBGGR10_1X10;
1140 	asd->fmt[ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE].fmt.code =
1141 	    MEDIA_BUS_FMT_SBGGR10_1X10;
1142 	asd->fmt[ATOMISP_SUBDEV_PAD_SOURCE_VIDEO].fmt.code =
1143 	    MEDIA_BUS_FMT_SBGGR10_1X10;
1144 
1145 	me->ops = &isp_subdev_media_ops;
1146 	me->function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
1147 	ret = media_entity_pads_init(me, ATOMISP_SUBDEV_PADS_NUM, pads);
1148 	if (ret < 0)
1149 		return ret;
1150 
1151 	atomisp_init_subdev_pipe(asd, &asd->video_in,
1152 				 V4L2_BUF_TYPE_VIDEO_OUTPUT);
1153 
1154 	atomisp_init_subdev_pipe(asd, &asd->video_out_preview,
1155 				 V4L2_BUF_TYPE_VIDEO_CAPTURE);
1156 
1157 	atomisp_init_subdev_pipe(asd, &asd->video_out_vf,
1158 				 V4L2_BUF_TYPE_VIDEO_CAPTURE);
1159 
1160 	atomisp_init_subdev_pipe(asd, &asd->video_out_capture,
1161 				 V4L2_BUF_TYPE_VIDEO_CAPTURE);
1162 
1163 	atomisp_init_subdev_pipe(asd, &asd->video_out_video_capture,
1164 				 V4L2_BUF_TYPE_VIDEO_CAPTURE);
1165 
1166 	atomisp_init_acc_pipe(asd, &asd->video_acc);
1167 
1168 	ret = atomisp_video_init(&asd->video_in, "MEMORY");
1169 	if (ret < 0)
1170 		return ret;
1171 
1172 	ret = atomisp_video_init(&asd->video_out_capture, "CAPTURE");
1173 	if (ret < 0)
1174 		return ret;
1175 
1176 	ret = atomisp_video_init(&asd->video_out_vf, "VIEWFINDER");
1177 	if (ret < 0)
1178 		return ret;
1179 
1180 	ret = atomisp_video_init(&asd->video_out_preview, "PREVIEW");
1181 	if (ret < 0)
1182 		return ret;
1183 
1184 	ret = atomisp_video_init(&asd->video_out_video_capture, "VIDEO");
1185 	if (ret < 0)
1186 		return ret;
1187 
1188 	atomisp_acc_init(&asd->video_acc, "ACC");
1189 
1190 	ret = v4l2_ctrl_handler_init(&asd->ctrl_handler, 1);
1191 	if (ret)
1192 		return ret;
1193 
1194 	asd->fmt_auto = v4l2_ctrl_new_custom(&asd->ctrl_handler,
1195 					     &ctrl_fmt_auto, NULL);
1196 	asd->run_mode = v4l2_ctrl_new_custom(&asd->ctrl_handler,
1197 					     &ctrl_run_mode, NULL);
1198 	asd->vfpp = v4l2_ctrl_new_custom(&asd->ctrl_handler,
1199 					 &ctrl_vfpp, NULL);
1200 	asd->continuous_mode = v4l2_ctrl_new_custom(&asd->ctrl_handler,
1201 			       &ctrl_continuous_mode, NULL);
1202 	asd->continuous_viewfinder = v4l2_ctrl_new_custom(&asd->ctrl_handler,
1203 				     &ctrl_continuous_viewfinder,
1204 				     NULL);
1205 	asd->continuous_raw_buffer_size =
1206 	    v4l2_ctrl_new_custom(&asd->ctrl_handler,
1207 				 &ctrl_continuous_raw_buffer_size,
1208 				 NULL);
1209 
1210 	asd->enable_raw_buffer_lock =
1211 	    v4l2_ctrl_new_custom(&asd->ctrl_handler,
1212 				 &ctrl_enable_raw_buffer_lock,
1213 				 NULL);
1214 	asd->depth_mode =
1215 	    v4l2_ctrl_new_custom(&asd->ctrl_handler,
1216 				 &ctrl_depth_mode,
1217 				 NULL);
1218 	asd->disable_dz =
1219 	    v4l2_ctrl_new_custom(&asd->ctrl_handler,
1220 				 &ctrl_disable_dz,
1221 				 NULL);
1222 	if (atomisp_hw_is_isp2401) {
1223 		asd->select_isp_version = v4l2_ctrl_new_custom(&asd->ctrl_handler,
1224 							       &ctrl_select_isp_version,
1225 							       NULL);
1226 #if 0 /* #ifdef CONFIG_ION */
1227 		asd->ion_dev_fd = v4l2_ctrl_new_custom(&asd->ctrl_handler,
1228 						       &ctrl_ion_dev_fd,
1229 						       NULL);
1230 #endif
1231 	}
1232 
1233 	/* Make controls visible on subdev as well. */
1234 	asd->subdev.ctrl_handler = &asd->ctrl_handler;
1235 	spin_lock_init(&asd->raw_buffer_bitmap_lock);
1236 	return asd->ctrl_handler.error;
1237 }
1238 
1239 int atomisp_create_pads_links(struct atomisp_device *isp)
1240 {
1241 	struct atomisp_sub_device *asd;
1242 	int i, j, ret = 0;
1243 
1244 	isp->num_of_streams = 2;
1245 	for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) {
1246 		for (j = 0; j < isp->num_of_streams; j++) {
1247 			ret =
1248 			    media_create_pad_link(&isp->csi2_port[i].subdev.
1249 						  entity, CSI2_PAD_SOURCE,
1250 						  &isp->asd[j].subdev.entity,
1251 						  ATOMISP_SUBDEV_PAD_SINK, 0);
1252 			if (ret < 0)
1253 				return ret;
1254 		}
1255 	}
1256 	for (i = 0; i < isp->input_cnt - 2; i++) {
1257 		ret = media_create_pad_link(&isp->inputs[i].camera->entity, 0,
1258 					    &isp->csi2_port[isp->inputs[i].
1259 						    port].subdev.entity,
1260 					    CSI2_PAD_SINK,
1261 					    MEDIA_LNK_FL_ENABLED |
1262 					    MEDIA_LNK_FL_IMMUTABLE);
1263 		if (ret < 0)
1264 			return ret;
1265 	}
1266 	for (i = 0; i < isp->num_of_streams; i++) {
1267 		asd = &isp->asd[i];
1268 		ret = media_create_pad_link(&asd->subdev.entity,
1269 					    ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW,
1270 					    &asd->video_out_preview.vdev.entity,
1271 					    0, 0);
1272 		if (ret < 0)
1273 			return ret;
1274 		ret = media_create_pad_link(&asd->subdev.entity,
1275 					    ATOMISP_SUBDEV_PAD_SOURCE_VF,
1276 					    &asd->video_out_vf.vdev.entity, 0,
1277 					    0);
1278 		if (ret < 0)
1279 			return ret;
1280 		ret = media_create_pad_link(&asd->subdev.entity,
1281 					    ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE,
1282 					    &asd->video_out_capture.vdev.entity,
1283 					    0, 0);
1284 		if (ret < 0)
1285 			return ret;
1286 		ret = media_create_pad_link(&asd->subdev.entity,
1287 					    ATOMISP_SUBDEV_PAD_SOURCE_VIDEO,
1288 					    &asd->video_out_video_capture.vdev.
1289 					    entity, 0, 0);
1290 		if (ret < 0)
1291 			return ret;
1292 		/*
1293 		 * file input only supported on subdev0
1294 		 * so do not create pad link for subdevs other then subdev0
1295 		 */
1296 		if (asd->index)
1297 			return 0;
1298 		ret = media_create_pad_link(&asd->video_in.vdev.entity,
1299 					    0, &asd->subdev.entity,
1300 					    ATOMISP_SUBDEV_PAD_SINK, 0);
1301 		if (ret < 0)
1302 			return ret;
1303 	}
1304 	return 0;
1305 }
1306 
1307 static void atomisp_subdev_cleanup_entities(struct atomisp_sub_device *asd)
1308 {
1309 	v4l2_ctrl_handler_free(&asd->ctrl_handler);
1310 
1311 	media_entity_cleanup(&asd->subdev.entity);
1312 }
1313 
1314 void atomisp_subdev_cleanup_pending_events(struct atomisp_sub_device *asd)
1315 {
1316 	struct v4l2_fh *fh, *fh_tmp;
1317 	struct v4l2_event event;
1318 	unsigned int i, pending_event;
1319 
1320 	list_for_each_entry_safe(fh, fh_tmp,
1321 				 &asd->subdev.devnode->fh_list, list) {
1322 		pending_event = v4l2_event_pending(fh);
1323 		for (i = 0; i < pending_event; i++)
1324 			v4l2_event_dequeue(fh, &event, 1);
1325 	}
1326 }
1327 
1328 void atomisp_subdev_unregister_entities(struct atomisp_sub_device *asd)
1329 {
1330 	atomisp_subdev_cleanup_entities(asd);
1331 	v4l2_device_unregister_subdev(&asd->subdev);
1332 	atomisp_video_unregister(&asd->video_in);
1333 	atomisp_video_unregister(&asd->video_out_preview);
1334 	atomisp_video_unregister(&asd->video_out_vf);
1335 	atomisp_video_unregister(&asd->video_out_capture);
1336 	atomisp_video_unregister(&asd->video_out_video_capture);
1337 	atomisp_acc_unregister(&asd->video_acc);
1338 }
1339 
1340 int atomisp_subdev_register_entities(struct atomisp_sub_device *asd,
1341 				     struct v4l2_device *vdev)
1342 {
1343 	int ret;
1344 
1345 	/* Register the subdev and video node. */
1346 	ret = v4l2_device_register_subdev(vdev, &asd->subdev);
1347 	if (ret < 0)
1348 		goto error;
1349 
1350 	ret = atomisp_video_register(&asd->video_out_capture, vdev);
1351 	if (ret < 0)
1352 		goto error;
1353 
1354 	ret = atomisp_video_register(&asd->video_out_vf, vdev);
1355 	if (ret < 0)
1356 		goto error;
1357 
1358 	ret = atomisp_video_register(&asd->video_out_preview, vdev);
1359 	if (ret < 0)
1360 		goto error;
1361 
1362 	ret = atomisp_video_register(&asd->video_out_video_capture, vdev);
1363 	if (ret < 0)
1364 		goto error;
1365 
1366 	ret = atomisp_acc_register(&asd->video_acc, vdev);
1367 	if (ret < 0)
1368 		goto error;
1369 
1370 	/*
1371 	 * file input only supported on subdev0
1372 	 * so do not create video node for subdevs other then subdev0
1373 	 */
1374 	if (asd->index)
1375 		return 0;
1376 	ret = atomisp_video_register(&asd->video_in, vdev);
1377 	if (ret < 0)
1378 		goto error;
1379 
1380 	return 0;
1381 
1382 error:
1383 	atomisp_subdev_unregister_entities(asd);
1384 	return ret;
1385 }
1386 
1387 /*
1388  * atomisp_subdev_init - ISP Subdevice  initialization.
1389  * @dev: Device pointer specific to the ATOM ISP.
1390  *
1391  * TODO: Get the initialisation values from platform data.
1392  *
1393  * Return 0 on success or a negative error code otherwise.
1394  */
1395 int atomisp_subdev_init(struct atomisp_device *isp)
1396 {
1397 	struct atomisp_sub_device *asd;
1398 	int i, ret = 0;
1399 
1400 	/*
1401 	 * CSS2.0 running ISP2400 support
1402 	 * multiple streams
1403 	 */
1404 	isp->num_of_streams = 2;
1405 	isp->asd = devm_kzalloc(isp->dev, sizeof(struct atomisp_sub_device) *
1406 				isp->num_of_streams, GFP_KERNEL);
1407 	if (!isp->asd)
1408 		return -ENOMEM;
1409 	for (i = 0; i < isp->num_of_streams; i++) {
1410 		asd = &isp->asd[i];
1411 		spin_lock_init(&asd->lock);
1412 		asd->isp = isp;
1413 		isp_subdev_init_params(asd);
1414 		asd->index = i;
1415 		ret = isp_subdev_init_entities(asd);
1416 		if (ret < 0) {
1417 			atomisp_subdev_cleanup_entities(asd);
1418 			break;
1419 		}
1420 	}
1421 
1422 	return ret;
1423 }
1424