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