GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / staging / media / atomisp / pci / atomisp_subdev.c
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_state *sd_state,
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_state *sd_state,
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, sd_state, pad);
259                 case V4L2_SEL_TGT_COMPOSE:
260                         return v4l2_subdev_get_try_compose(sd, sd_state, 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_state *sd_state, 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, sd_state, 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_state *sd_state,
289                              uint32_t which,
290                              struct v4l2_mbus_framefmt **ffmt,
291                              struct v4l2_rect *crop[ATOMISP_SUBDEV_PADS_NUM],
292                              struct v4l2_rect *comp[ATOMISP_SUBDEV_PADS_NUM])
293 {
294         unsigned int i;
295
296         for (i = 0; i < ATOMISP_SUBDEV_PADS_NUM; i++) {
297                 ffmt[i] = atomisp_subdev_get_ffmt(sd, sd_state, which, i);
298                 crop[i] = atomisp_subdev_get_rect(sd, sd_state, which, i,
299                                                   V4L2_SEL_TGT_CROP);
300                 comp[i] = atomisp_subdev_get_rect(sd, sd_state, which, i,
301                                                   V4L2_SEL_TGT_COMPOSE);
302         }
303 }
304
305 static void isp_subdev_propagate(struct v4l2_subdev *sd,
306                                  struct v4l2_subdev_state *sd_state,
307                                  u32 which, uint32_t pad, uint32_t target,
308                                  uint32_t flags)
309 {
310         struct v4l2_mbus_framefmt *ffmt[ATOMISP_SUBDEV_PADS_NUM];
311         struct v4l2_rect *crop[ATOMISP_SUBDEV_PADS_NUM],
312                        *comp[ATOMISP_SUBDEV_PADS_NUM];
313
314         if (flags & V4L2_SEL_FLAG_KEEP_CONFIG)
315                 return;
316
317         isp_get_fmt_rect(sd, sd_state, which, ffmt, crop, comp);
318
319         switch (pad) {
320         case ATOMISP_SUBDEV_PAD_SINK: {
321                 struct v4l2_rect r = {0};
322
323                 /* Only crop target supported on sink pad. */
324                 r.width = ffmt[pad]->width;
325                 r.height = ffmt[pad]->height;
326
327                 atomisp_subdev_set_selection(sd, sd_state, which, pad,
328                                              target, flags, &r);
329                 break;
330         }
331         }
332 }
333
334 static int isp_subdev_get_selection(struct v4l2_subdev *sd,
335                                     struct v4l2_subdev_state *sd_state,
336                                     struct v4l2_subdev_selection *sel)
337 {
338         struct v4l2_rect *rec;
339         int rval = isp_subdev_validate_rect(sd, sel->pad, sel->target);
340
341         if (rval)
342                 return rval;
343
344         rec = atomisp_subdev_get_rect(sd, sd_state, sel->which, sel->pad,
345                                       sel->target);
346         if (!rec)
347                 return -EINVAL;
348
349         sel->r = *rec;
350         return 0;
351 }
352
353 static const char *atomisp_pad_str(unsigned int pad)
354 {
355         static const char *const pad_str[] = {
356                 "ATOMISP_SUBDEV_PAD_SINK",
357                 "ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE",
358                 "ATOMISP_SUBDEV_PAD_SOURCE_VF",
359                 "ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW",
360                 "ATOMISP_SUBDEV_PAD_SOURCE_VIDEO",
361         };
362
363         if (pad >= ARRAY_SIZE(pad_str))
364                 return "ATOMISP_INVALID_PAD";
365         return pad_str[pad];
366 }
367
368 int atomisp_subdev_set_selection(struct v4l2_subdev *sd,
369                                  struct v4l2_subdev_state *sd_state,
370                                  u32 which, uint32_t pad, uint32_t target,
371                                  u32 flags, struct v4l2_rect *r)
372 {
373         struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd);
374         struct atomisp_device *isp = isp_sd->isp;
375         struct v4l2_mbus_framefmt *ffmt[ATOMISP_SUBDEV_PADS_NUM];
376         u16 vdev_pad = atomisp_subdev_source_pad(sd->devnode);
377         struct v4l2_rect *crop[ATOMISP_SUBDEV_PADS_NUM],
378                        *comp[ATOMISP_SUBDEV_PADS_NUM];
379         enum atomisp_input_stream_id stream_id;
380         unsigned int i;
381         unsigned int padding_w = pad_w;
382         unsigned int padding_h = pad_h;
383
384         stream_id = atomisp_source_pad_to_stream_id(isp_sd, vdev_pad);
385
386         isp_get_fmt_rect(sd, sd_state, which, ffmt, crop, comp);
387
388         dev_dbg(isp->dev,
389                 "sel: pad %s tgt %s l %d t %d w %d h %d which %s f 0x%8.8x\n",
390                 atomisp_pad_str(pad), target == V4L2_SEL_TGT_CROP
391                 ? "V4L2_SEL_TGT_CROP" : "V4L2_SEL_TGT_COMPOSE",
392                 r->left, r->top, r->width, r->height,
393                 which == V4L2_SUBDEV_FORMAT_TRY ? "V4L2_SUBDEV_FORMAT_TRY"
394                 : "V4L2_SUBDEV_FORMAT_ACTIVE", flags);
395
396         r->width = rounddown(r->width, ATOM_ISP_STEP_WIDTH);
397         r->height = rounddown(r->height, ATOM_ISP_STEP_HEIGHT);
398
399         switch (pad) {
400         case ATOMISP_SUBDEV_PAD_SINK: {
401                 /* Only crop target supported on sink pad. */
402                 unsigned int dvs_w, dvs_h;
403
404                 crop[pad]->width = ffmt[pad]->width;
405                 crop[pad]->height = ffmt[pad]->height;
406
407                 /* Workaround for BYT 1080p perfectshot since the maxinum resolution of
408                  * front camera ov2722 is 1932x1092 and cannot use pad_w > 12*/
409                 if (!strncmp(isp->inputs[isp_sd->input_curr].camera->name,
410                              "ov2722", 6) && crop[pad]->height == 1092) {
411                         padding_w = 12;
412                         padding_h = 12;
413                 }
414
415                 if (isp->inputs[isp_sd->input_curr].type == SOC_CAMERA) {
416                         padding_w = 0;
417                         padding_h = 0;
418                 }
419
420                 if (atomisp_subdev_format_conversion(isp_sd,
421                                                      isp_sd->capture_pad)
422                     && crop[pad]->width && crop[pad]->height) {
423                         crop[pad]->width -= padding_w;
424                         crop[pad]->height -= padding_h;
425                 }
426
427                 /* if subdev type is SOC camera,we do not need to set DVS */
428                 if (isp->inputs[isp_sd->input_curr].type == SOC_CAMERA)
429                         isp_sd->params.video_dis_en = 0;
430
431                 if (isp_sd->params.video_dis_en &&
432                     isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO &&
433                     !isp_sd->continuous_mode->val) {
434                         /* This resolution contains 20 % of DVS slack
435                          * (of the desired captured image before
436                          * scaling, or 1 / 6 of what we get from the
437                          * sensor) in both width and height. Remove
438                          * it. */
439                         crop[pad]->width = roundup(crop[pad]->width * 5 / 6,
440                                                    ATOM_ISP_STEP_WIDTH);
441                         crop[pad]->height = roundup(crop[pad]->height * 5 / 6,
442                                                     ATOM_ISP_STEP_HEIGHT);
443                 }
444
445                 crop[pad]->width = min(crop[pad]->width, r->width);
446                 crop[pad]->height = min(crop[pad]->height, r->height);
447
448                 if (!(flags & V4L2_SEL_FLAG_KEEP_CONFIG)) {
449                         for (i = ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE;
450                              i < ATOMISP_SUBDEV_PADS_NUM; i++) {
451                                 struct v4l2_rect tmp = *crop[pad];
452
453                                 atomisp_subdev_set_selection(
454                                     sd, sd_state, which, i,
455                                     V4L2_SEL_TGT_COMPOSE,
456                                     flags, &tmp);
457                         }
458                 }
459
460                 if (which == V4L2_SUBDEV_FORMAT_TRY)
461                         break;
462
463                 if (isp_sd->params.video_dis_en &&
464                     isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO &&
465                     !isp_sd->continuous_mode->val) {
466                         dvs_w = rounddown(crop[pad]->width / 5,
467                                           ATOM_ISP_STEP_WIDTH);
468                         dvs_h = rounddown(crop[pad]->height / 5,
469                                           ATOM_ISP_STEP_HEIGHT);
470                 } else if (!isp_sd->params.video_dis_en &&
471                            isp_sd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
472                         /*
473                          * For CSS2.0, digital zoom needs to set dvs envelope to 12
474                          * when dvs is disabled.
475                          */
476                         dvs_w = dvs_h = 12;
477                 } else {
478                         dvs_w = dvs_h = 0;
479                 }
480                 atomisp_css_video_set_dis_envelope(isp_sd, dvs_w, dvs_h);
481                 atomisp_css_input_set_effective_resolution(isp_sd, stream_id,
482                         crop[pad]->width, crop[pad]->height);
483
484                 break;
485         }
486         case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE:
487         case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO: {
488                 /* Only compose target is supported on source pads. */
489
490                 if (isp_sd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) {
491                         /* Scaling is disabled in this mode */
492                         r->width = crop[ATOMISP_SUBDEV_PAD_SINK]->width;
493                         r->height = crop[ATOMISP_SUBDEV_PAD_SINK]->height;
494                 }
495
496                 if (crop[ATOMISP_SUBDEV_PAD_SINK]->width == r->width
497                     && crop[ATOMISP_SUBDEV_PAD_SINK]->height == r->height)
498                         isp_sd->params.yuv_ds_en = false;
499                 else
500                         isp_sd->params.yuv_ds_en = true;
501
502                 comp[pad]->width = r->width;
503                 comp[pad]->height = r->height;
504
505                 if (r->width == 0 || r->height == 0 ||
506                     crop[ATOMISP_SUBDEV_PAD_SINK]->width == 0 ||
507                     crop[ATOMISP_SUBDEV_PAD_SINK]->height == 0)
508                         break;
509                 /*
510                  * do cropping on sensor input if ratio of required resolution
511                  * is different with sensor output resolution ratio:
512                  *
513                  * ratio = width / height
514                  *
515                  * if ratio_output < ratio_sensor:
516                  *      effect_width = sensor_height * out_width / out_height;
517                  *      effect_height = sensor_height;
518                  * else
519                  *      effect_width = sensor_width;
520                  *      effect_height = sensor_width * out_height / out_width;
521                  *
522                  */
523                 if (r->width * crop[ATOMISP_SUBDEV_PAD_SINK]->height <
524                     crop[ATOMISP_SUBDEV_PAD_SINK]->width * r->height)
525                         atomisp_css_input_set_effective_resolution(isp_sd,
526                                 stream_id,
527                                 rounddown(crop[ATOMISP_SUBDEV_PAD_SINK]->
528                                           height * r->width / r->height,
529                                           ATOM_ISP_STEP_WIDTH),
530                                 crop[ATOMISP_SUBDEV_PAD_SINK]->height);
531                 else
532                         atomisp_css_input_set_effective_resolution(isp_sd,
533                                 stream_id,
534                                 crop[ATOMISP_SUBDEV_PAD_SINK]->width,
535                                 rounddown(crop[ATOMISP_SUBDEV_PAD_SINK]->
536                                           width * r->height / r->width,
537                                           ATOM_ISP_STEP_WIDTH));
538
539                 break;
540         }
541         case ATOMISP_SUBDEV_PAD_SOURCE_VF:
542         case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW:
543                 comp[pad]->width = r->width;
544                 comp[pad]->height = r->height;
545                 break;
546         default:
547                 return -EINVAL;
548         }
549
550         /* Set format dimensions on non-sink pads as well. */
551         if (pad != ATOMISP_SUBDEV_PAD_SINK) {
552                 ffmt[pad]->width = comp[pad]->width;
553                 ffmt[pad]->height = comp[pad]->height;
554         }
555
556         if (!atomisp_subdev_get_rect(sd, sd_state, which, pad, target))
557                 return -EINVAL;
558         *r = *atomisp_subdev_get_rect(sd, sd_state, which, pad, target);
559
560         dev_dbg(isp->dev, "sel actual: l %d t %d w %d h %d\n",
561                 r->left, r->top, r->width, r->height);
562
563         return 0;
564 }
565
566 static int isp_subdev_set_selection(struct v4l2_subdev *sd,
567                                     struct v4l2_subdev_state *sd_state,
568                                     struct v4l2_subdev_selection *sel)
569 {
570         int rval = isp_subdev_validate_rect(sd, sel->pad, sel->target);
571
572         if (rval)
573                 return rval;
574
575         return atomisp_subdev_set_selection(sd, sd_state, sel->which,
576                                             sel->pad,
577                                             sel->target, sel->flags, &sel->r);
578 }
579
580 static int atomisp_get_sensor_bin_factor(struct atomisp_sub_device *asd)
581 {
582         struct v4l2_control ctrl = {0};
583         struct atomisp_device *isp = asd->isp;
584         int hbin, vbin;
585         int ret;
586
587         if (isp->inputs[asd->input_curr].type == FILE_INPUT ||
588             isp->inputs[asd->input_curr].type == TEST_PATTERN)
589                 return 0;
590
591         ctrl.id = V4L2_CID_BIN_FACTOR_HORZ;
592         ret =
593             v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->ctrl_handler,
594                         &ctrl);
595         hbin = ctrl.value;
596         ctrl.id = V4L2_CID_BIN_FACTOR_VERT;
597         ret |=
598             v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->ctrl_handler,
599                         &ctrl);
600         vbin = ctrl.value;
601
602         /*
603          * ISP needs to know binning factor from sensor.
604          * In case horizontal and vertical sensor's binning factors
605          * are different or sensor does not support binning factor CID,
606          * ISP will apply default 0 value.
607          */
608         if (ret || hbin != vbin)
609                 hbin = 0;
610
611         return hbin;
612 }
613
614 void atomisp_subdev_set_ffmt(struct v4l2_subdev *sd,
615                              struct v4l2_subdev_state *sd_state,
616                              uint32_t which,
617                              u32 pad, struct v4l2_mbus_framefmt *ffmt)
618 {
619         struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd);
620         struct atomisp_device *isp = isp_sd->isp;
621         struct v4l2_mbus_framefmt *__ffmt =
622             atomisp_subdev_get_ffmt(sd, sd_state, which, pad);
623         u16 vdev_pad = atomisp_subdev_source_pad(sd->devnode);
624         enum atomisp_input_stream_id stream_id;
625
626         dev_dbg(isp->dev, "ffmt: pad %s w %d h %d code 0x%8.8x which %s\n",
627                 atomisp_pad_str(pad), ffmt->width, ffmt->height, ffmt->code,
628                 which == V4L2_SUBDEV_FORMAT_TRY ? "V4L2_SUBDEV_FORMAT_TRY"
629                 : "V4L2_SUBDEV_FORMAT_ACTIVE");
630
631         stream_id = atomisp_source_pad_to_stream_id(isp_sd, vdev_pad);
632
633         switch (pad) {
634         case ATOMISP_SUBDEV_PAD_SINK: {
635                 const struct atomisp_in_fmt_conv *fc =
636                     atomisp_find_in_fmt_conv(ffmt->code);
637
638                 if (!fc) {
639                         fc = atomisp_in_fmt_conv;
640                         ffmt->code = fc->code;
641                         dev_dbg(isp->dev, "using 0x%8.8x instead\n",
642                                 ffmt->code);
643                 }
644
645                 *__ffmt = *ffmt;
646
647                 isp_subdev_propagate(sd, sd_state, which, pad,
648                                      V4L2_SEL_TGT_CROP, 0);
649
650                 if (which == V4L2_SUBDEV_FORMAT_ACTIVE) {
651                         atomisp_css_input_set_resolution(isp_sd,
652                                                          stream_id, ffmt);
653                         atomisp_css_input_set_binning_factor(isp_sd,
654                                                              stream_id,
655                                                              atomisp_get_sensor_bin_factor(isp_sd));
656                         atomisp_css_input_set_bayer_order(isp_sd, stream_id,
657                                                           fc->bayer_order);
658                         atomisp_css_input_set_format(isp_sd, stream_id,
659                                                      fc->atomisp_in_fmt);
660                         atomisp_css_set_default_isys_config(isp_sd, stream_id,
661                                                             ffmt);
662                 }
663
664                 break;
665         }
666         case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE:
667         case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW:
668         case ATOMISP_SUBDEV_PAD_SOURCE_VF:
669         case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO:
670                 __ffmt->code = ffmt->code;
671                 break;
672         }
673 }
674
675 /*
676  * isp_subdev_get_format - Retrieve the video format on a pad
677  * @sd : ISP V4L2 subdevice
678  * @fh : V4L2 subdev file handle
679  * @pad: Pad number
680  * @fmt: Format
681  *
682  * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
683  * to the format type.
684  */
685 static int isp_subdev_get_format(struct v4l2_subdev *sd,
686                                  struct v4l2_subdev_state *sd_state,
687                                  struct v4l2_subdev_format *fmt)
688 {
689         fmt->format = *atomisp_subdev_get_ffmt(sd, sd_state, fmt->which,
690                                                fmt->pad);
691
692         return 0;
693 }
694
695 /*
696  * isp_subdev_set_format - Set the video format on a pad
697  * @sd : ISP subdev V4L2 subdevice
698  * @fh : V4L2 subdev file handle
699  * @pad: Pad number
700  * @fmt: Format
701  *
702  * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
703  * to the format type.
704  */
705 static int isp_subdev_set_format(struct v4l2_subdev *sd,
706                                  struct v4l2_subdev_state *sd_state,
707                                  struct v4l2_subdev_format *fmt)
708 {
709         atomisp_subdev_set_ffmt(sd, sd_state, fmt->which, fmt->pad,
710                                 &fmt->format);
711
712         return 0;
713 }
714
715 /* V4L2 subdev core operations */
716 static const struct v4l2_subdev_core_ops isp_subdev_v4l2_core_ops = {
717         .ioctl = isp_subdev_ioctl, .s_power = isp_subdev_set_power,
718         .subscribe_event = isp_subdev_subscribe_event,
719         .unsubscribe_event = isp_subdev_unsubscribe_event,
720 };
721
722 /* V4L2 subdev pad operations */
723 static const struct v4l2_subdev_pad_ops isp_subdev_v4l2_pad_ops = {
724         .enum_mbus_code = isp_subdev_enum_mbus_code,
725         .get_fmt = isp_subdev_get_format,
726         .set_fmt = isp_subdev_set_format,
727         .get_selection = isp_subdev_get_selection,
728         .set_selection = isp_subdev_set_selection,
729         .link_validate = v4l2_subdev_link_validate_default,
730 };
731
732 /* V4L2 subdev operations */
733 static const struct v4l2_subdev_ops isp_subdev_v4l2_ops = {
734         .core = &isp_subdev_v4l2_core_ops,
735         .pad = &isp_subdev_v4l2_pad_ops,
736 };
737
738 static void isp_subdev_init_params(struct atomisp_sub_device *asd)
739 {
740         unsigned int i;
741
742         /* parameters initialization */
743         INIT_LIST_HEAD(&asd->s3a_stats);
744         INIT_LIST_HEAD(&asd->s3a_stats_in_css);
745         INIT_LIST_HEAD(&asd->s3a_stats_ready);
746         INIT_LIST_HEAD(&asd->dis_stats);
747         INIT_LIST_HEAD(&asd->dis_stats_in_css);
748         spin_lock_init(&asd->dis_stats_lock);
749         for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
750                 INIT_LIST_HEAD(&asd->metadata[i]);
751                 INIT_LIST_HEAD(&asd->metadata_in_css[i]);
752                 INIT_LIST_HEAD(&asd->metadata_ready[i]);
753         }
754 }
755
756 /*
757 * isp_subdev_link_setup - Setup isp subdev connections
758 * @entity: ispsubdev media entity
759 * @local: Pad at the local end of the link
760 * @remote: Pad at the remote end of the link
761 * @flags: Link flags
762 *
763 * return -EINVAL or zero on success
764 */
765 static int isp_subdev_link_setup(struct media_entity *entity,
766                                  const struct media_pad *local,
767                                  const struct media_pad *remote, u32 flags)
768 {
769         struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
770         struct atomisp_sub_device *isp_sd = v4l2_get_subdevdata(sd);
771         struct atomisp_device *isp = isp_sd->isp;
772         unsigned int i;
773
774         switch (local->index | is_media_entity_v4l2_subdev(remote->entity)) {
775         case ATOMISP_SUBDEV_PAD_SINK | MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN:
776                 /* Read from the sensor CSI2-ports. */
777                 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
778                         isp_sd->input = ATOMISP_SUBDEV_INPUT_NONE;
779                         break;
780                 }
781
782                 if (isp_sd->input != ATOMISP_SUBDEV_INPUT_NONE)
783                         return -EBUSY;
784
785                 for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) {
786                         if (remote->entity != &isp->csi2_port[i].subdev.entity)
787                                 continue;
788
789                         isp_sd->input = ATOMISP_SUBDEV_INPUT_CSI2_PORT1 + i;
790                         return 0;
791                 }
792
793                 return -EINVAL;
794
795         case ATOMISP_SUBDEV_PAD_SINK | MEDIA_ENT_F_OLD_BASE:
796                 /* read from memory */
797                 if (flags & MEDIA_LNK_FL_ENABLED) {
798                         if (isp_sd->input >= ATOMISP_SUBDEV_INPUT_CSI2_PORT1 &&
799                             isp_sd->input < (ATOMISP_SUBDEV_INPUT_CSI2_PORT1
800                                              + ATOMISP_CAMERA_NR_PORTS))
801                                 return -EBUSY;
802                         isp_sd->input = ATOMISP_SUBDEV_INPUT_MEMORY;
803                 } else {
804                         if (isp_sd->input == ATOMISP_SUBDEV_INPUT_MEMORY)
805                                 isp_sd->input = ATOMISP_SUBDEV_INPUT_NONE;
806                 }
807                 break;
808
809         case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW | MEDIA_ENT_F_OLD_BASE:
810                 /* always write to memory */
811                 break;
812
813         case ATOMISP_SUBDEV_PAD_SOURCE_VF | MEDIA_ENT_F_OLD_BASE:
814                 /* always write to memory */
815                 break;
816
817         case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE | MEDIA_ENT_F_OLD_BASE:
818                 /* always write to memory */
819                 break;
820
821         case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO | MEDIA_ENT_F_OLD_BASE:
822                 /* always write to memory */
823                 break;
824
825         default:
826                 return -EINVAL;
827         }
828
829         return 0;
830 }
831
832 /* media operations */
833 static const struct media_entity_operations isp_subdev_media_ops = {
834         .link_setup = isp_subdev_link_setup,
835         .link_validate = v4l2_subdev_link_validate,
836         /*       .set_power = v4l2_subdev_set_power,    */
837 };
838
839 static int __atomisp_update_run_mode(struct atomisp_sub_device *asd)
840 {
841         struct atomisp_device *isp = asd->isp;
842         struct v4l2_ctrl *ctrl = asd->run_mode;
843         struct v4l2_ctrl *c;
844         s32 mode;
845
846         if (ctrl->val != ATOMISP_RUN_MODE_VIDEO &&
847             asd->continuous_mode->val)
848                 mode = ATOMISP_RUN_MODE_PREVIEW;
849         else
850                 mode = ctrl->val;
851
852         c = v4l2_ctrl_find(
853                 isp->inputs[asd->input_curr].camera->ctrl_handler,
854                 V4L2_CID_RUN_MODE);
855
856         if (c)
857                 return v4l2_ctrl_s_ctrl(c, mode);
858
859         return 0;
860 }
861
862 int atomisp_update_run_mode(struct atomisp_sub_device *asd)
863 {
864         int rval;
865
866         mutex_lock(asd->ctrl_handler.lock);
867         rval = __atomisp_update_run_mode(asd);
868         mutex_unlock(asd->ctrl_handler.lock);
869
870         return rval;
871 }
872
873 static int s_ctrl(struct v4l2_ctrl *ctrl)
874 {
875         struct atomisp_sub_device *asd = container_of(
876                                              ctrl->handler, struct atomisp_sub_device, ctrl_handler);
877
878         switch (ctrl->id) {
879         case V4L2_CID_RUN_MODE:
880                 return __atomisp_update_run_mode(asd);
881         case V4L2_CID_DEPTH_MODE:
882                 if (asd->streaming != ATOMISP_DEVICE_STREAMING_DISABLED) {
883                         dev_err(asd->isp->dev,
884                                 "ISP is streaming, it is not supported to change the depth mode\n");
885                         return -EINVAL;
886                 }
887                 break;
888         }
889
890         return 0;
891 }
892
893 static const struct v4l2_ctrl_ops ctrl_ops = {
894         .s_ctrl = &s_ctrl,
895 };
896
897 static const struct v4l2_ctrl_config ctrl_fmt_auto = {
898         .ops = &ctrl_ops,
899         .id = V4L2_CID_FMT_AUTO,
900         .name = "Automatic format guessing",
901         .type = V4L2_CTRL_TYPE_BOOLEAN,
902         .min = 0,
903         .max = 1,
904         .step = 1,
905         .def = 1,
906 };
907
908 static const char *const ctrl_run_mode_menu[] = {
909         NULL,
910         "Video",
911         "Still capture",
912         "Continuous capture",
913         "Preview",
914 };
915
916 static const struct v4l2_ctrl_config ctrl_run_mode = {
917         .ops = &ctrl_ops,
918         .id = V4L2_CID_RUN_MODE,
919         .name = "Atomisp run mode",
920         .type = V4L2_CTRL_TYPE_MENU,
921         .min = 1,
922         .def = 1,
923         .max = 4,
924         .qmenu = ctrl_run_mode_menu,
925 };
926
927 static const char *const ctrl_vfpp_mode_menu[] = {
928         "Enable",                       /* vfpp always enabled */
929         "Disable to scaler mode",       /* CSS into video mode and disable */
930         "Disable to low latency mode",  /* CSS into still mode and disable */
931 };
932
933 static const struct v4l2_ctrl_config ctrl_vfpp = {
934         .id = V4L2_CID_VFPP,
935         .name = "Atomisp vf postprocess",
936         .type = V4L2_CTRL_TYPE_MENU,
937         .min = 0,
938         .def = 0,
939         .max = 2,
940         .qmenu = ctrl_vfpp_mode_menu,
941 };
942
943 /*
944  * Control for ISP continuous mode
945  *
946  * When enabled, capture processing is possible without
947  * stopping the preview pipeline. When disabled, ISP needs
948  * to be restarted between preview and capture.
949  */
950 static const struct v4l2_ctrl_config ctrl_continuous_mode = {
951         .ops = &ctrl_ops,
952         .id = V4L2_CID_ATOMISP_CONTINUOUS_MODE,
953         .type = V4L2_CTRL_TYPE_BOOLEAN,
954         .name = "Continuous mode",
955         .min = 0,
956         .max = 1,
957         .step = 1,
958         .def = 0,
959 };
960
961 /*
962  * Control for continuous mode raw buffer size
963  *
964  * The size of the RAW ringbuffer sets limit on how much
965  * back in time application can go when requesting capture
966  * frames to be rendered, and how many frames can be rendered
967  * in a burst at full sensor rate.
968  *
969  * Note: this setting has a big impact on memory consumption of
970  * the CSS subsystem.
971  */
972 static const struct v4l2_ctrl_config ctrl_continuous_raw_buffer_size = {
973         .ops = &ctrl_ops,
974         .id = V4L2_CID_ATOMISP_CONTINUOUS_RAW_BUFFER_SIZE,
975         .type = V4L2_CTRL_TYPE_INTEGER,
976         .name = "Continuous raw ringbuffer size",
977         .min = 1,
978         .max = 100, /* depends on CSS version, runtime checked */
979         .step = 1,
980         .def = 3,
981 };
982
983 /*
984  * Control for enabling continuous viewfinder
985  *
986  * When enabled, and ISP is in continuous mode (see ctrl_continuous_mode ),
987  * preview pipeline continues concurrently with capture
988  * processing. When disabled, and continuous mode is used,
989  * preview is paused while captures are processed, but
990  * full pipeline restart is not needed.
991  *
992  * By setting this to disabled, capture processing is
993  * essentially given priority over preview, and the effective
994  * capture output rate may be higher than with continuous
995  * viewfinder enabled.
996  */
997 static const struct v4l2_ctrl_config ctrl_continuous_viewfinder = {
998         .id = V4L2_CID_ATOMISP_CONTINUOUS_VIEWFINDER,
999         .type = V4L2_CTRL_TYPE_BOOLEAN,
1000         .name = "Continuous viewfinder",
1001         .min = 0,
1002         .max = 1,
1003         .step = 1,
1004         .def = 0,
1005 };
1006
1007 /*
1008  * Control for enabling Lock&Unlock Raw Buffer mechanism
1009  *
1010  * When enabled, Raw Buffer can be locked and unlocked.
1011  * Application can hold the exp_id of Raw Buffer
1012  * and unlock it when no longer needed.
1013  * Note: Make sure set this configuration before creating stream.
1014  */
1015 static const struct v4l2_ctrl_config ctrl_enable_raw_buffer_lock = {
1016         .id = V4L2_CID_ENABLE_RAW_BUFFER_LOCK,
1017         .type = V4L2_CTRL_TYPE_BOOLEAN,
1018         .name = "Lock Unlock Raw Buffer",
1019         .min = 0,
1020         .max = 1,
1021         .step = 1,
1022         .def = 0,
1023 };
1024
1025 /*
1026  * Control to disable digital zoom of the whole stream
1027  *
1028  * When it is true, pipe configuration enable_dz will be set to false.
1029  * This can help get a better performance by disabling pp binary.
1030  *
1031  * Note: Make sure set this configuration before creating stream.
1032  */
1033 static const struct v4l2_ctrl_config ctrl_disable_dz = {
1034         .id = V4L2_CID_DISABLE_DZ,
1035         .type = V4L2_CTRL_TYPE_BOOLEAN,
1036         .name = "Disable digital zoom",
1037         .min = 0,
1038         .max = 1,
1039         .step = 1,
1040         .def = 0,
1041 };
1042
1043 /*
1044  * Control for ISP depth mode
1045  *
1046  * When enabled, that means ISP will deal with dual streams and sensors will be
1047  * in slave/master mode.
1048  * slave sensor will have no output until master sensor is streamed on.
1049  */
1050 static const struct v4l2_ctrl_config ctrl_depth_mode = {
1051         .ops = &ctrl_ops,
1052         .id = V4L2_CID_DEPTH_MODE,
1053         .type = V4L2_CTRL_TYPE_BOOLEAN,
1054         .name = "Depth mode",
1055         .min = 0,
1056         .max = 1,
1057         .step = 1,
1058         .def = 0,
1059 };
1060
1061 static void atomisp_init_subdev_pipe(struct atomisp_sub_device *asd,
1062                                      struct atomisp_video_pipe *pipe, enum v4l2_buf_type buf_type)
1063 {
1064         pipe->type = buf_type;
1065         pipe->asd = asd;
1066         pipe->isp = asd->isp;
1067         spin_lock_init(&pipe->irq_lock);
1068         INIT_LIST_HEAD(&pipe->activeq);
1069         INIT_LIST_HEAD(&pipe->activeq_out);
1070         INIT_LIST_HEAD(&pipe->buffers_waiting_for_param);
1071         INIT_LIST_HEAD(&pipe->per_frame_params);
1072         memset(pipe->frame_request_config_id,
1073                0, VIDEO_MAX_FRAME * sizeof(unsigned int));
1074         memset(pipe->frame_params,
1075                0, VIDEO_MAX_FRAME *
1076                sizeof(struct atomisp_css_params_with_list *));
1077 }
1078
1079 static void atomisp_init_acc_pipe(struct atomisp_sub_device *asd,
1080                                   struct atomisp_acc_pipe *pipe)
1081 {
1082         pipe->asd = asd;
1083         pipe->isp = asd->isp;
1084         INIT_LIST_HEAD(&asd->acc.fw);
1085         INIT_LIST_HEAD(&asd->acc.memory_maps);
1086         ida_init(&asd->acc.ida);
1087 }
1088
1089 /*
1090  * isp_subdev_init_entities - Initialize V4L2 subdev and media entity
1091  * @asd: ISP CCDC module
1092  *
1093  * Return 0 on success and a negative error code on failure.
1094  */
1095 static int isp_subdev_init_entities(struct atomisp_sub_device *asd)
1096 {
1097         struct v4l2_subdev *sd = &asd->subdev;
1098         struct media_pad *pads = asd->pads;
1099         struct media_entity *me = &sd->entity;
1100         int ret;
1101
1102         asd->input = ATOMISP_SUBDEV_INPUT_NONE;
1103
1104         v4l2_subdev_init(sd, &isp_subdev_v4l2_ops);
1105         sprintf(sd->name, "ATOMISP_SUBDEV_%d", asd->index);
1106         v4l2_set_subdevdata(sd, asd);
1107         sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1108
1109         pads[ATOMISP_SUBDEV_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1110         pads[ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW].flags = MEDIA_PAD_FL_SOURCE;
1111         pads[ATOMISP_SUBDEV_PAD_SOURCE_VF].flags = MEDIA_PAD_FL_SOURCE;
1112         pads[ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE].flags = MEDIA_PAD_FL_SOURCE;
1113         pads[ATOMISP_SUBDEV_PAD_SOURCE_VIDEO].flags = MEDIA_PAD_FL_SOURCE;
1114
1115         asd->fmt[ATOMISP_SUBDEV_PAD_SINK].fmt.code =
1116             MEDIA_BUS_FMT_SBGGR10_1X10;
1117         asd->fmt[ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW].fmt.code =
1118             MEDIA_BUS_FMT_SBGGR10_1X10;
1119         asd->fmt[ATOMISP_SUBDEV_PAD_SOURCE_VF].fmt.code =
1120             MEDIA_BUS_FMT_SBGGR10_1X10;
1121         asd->fmt[ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE].fmt.code =
1122             MEDIA_BUS_FMT_SBGGR10_1X10;
1123         asd->fmt[ATOMISP_SUBDEV_PAD_SOURCE_VIDEO].fmt.code =
1124             MEDIA_BUS_FMT_SBGGR10_1X10;
1125
1126         me->ops = &isp_subdev_media_ops;
1127         me->function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
1128         ret = media_entity_pads_init(me, ATOMISP_SUBDEV_PADS_NUM, pads);
1129         if (ret < 0)
1130                 return ret;
1131
1132         atomisp_init_subdev_pipe(asd, &asd->video_in,
1133                                  V4L2_BUF_TYPE_VIDEO_OUTPUT);
1134
1135         atomisp_init_subdev_pipe(asd, &asd->video_out_preview,
1136                                  V4L2_BUF_TYPE_VIDEO_CAPTURE);
1137
1138         atomisp_init_subdev_pipe(asd, &asd->video_out_vf,
1139                                  V4L2_BUF_TYPE_VIDEO_CAPTURE);
1140
1141         atomisp_init_subdev_pipe(asd, &asd->video_out_capture,
1142                                  V4L2_BUF_TYPE_VIDEO_CAPTURE);
1143
1144         atomisp_init_subdev_pipe(asd, &asd->video_out_video_capture,
1145                                  V4L2_BUF_TYPE_VIDEO_CAPTURE);
1146
1147         atomisp_init_acc_pipe(asd, &asd->video_acc);
1148
1149         ret = atomisp_video_init(&asd->video_in, "MEMORY",
1150                                  ATOMISP_RUN_MODE_SDV);
1151         if (ret < 0)
1152                 return ret;
1153
1154         ret = atomisp_video_init(&asd->video_out_capture, "CAPTURE",
1155                                  ATOMISP_RUN_MODE_STILL_CAPTURE);
1156         if (ret < 0)
1157                 return ret;
1158
1159         ret = atomisp_video_init(&asd->video_out_vf, "VIEWFINDER",
1160                                  ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE);
1161         if (ret < 0)
1162                 return ret;
1163
1164         ret = atomisp_video_init(&asd->video_out_preview, "PREVIEW",
1165                                  ATOMISP_RUN_MODE_PREVIEW);
1166         if (ret < 0)
1167                 return ret;
1168
1169         ret = atomisp_video_init(&asd->video_out_video_capture, "VIDEO",
1170                                  ATOMISP_RUN_MODE_VIDEO);
1171         if (ret < 0)
1172                 return ret;
1173
1174         atomisp_acc_init(&asd->video_acc, "ACC");
1175
1176         ret = v4l2_ctrl_handler_init(&asd->ctrl_handler, 1);
1177         if (ret)
1178                 return ret;
1179
1180         asd->fmt_auto = v4l2_ctrl_new_custom(&asd->ctrl_handler,
1181                                              &ctrl_fmt_auto, NULL);
1182         asd->run_mode = v4l2_ctrl_new_custom(&asd->ctrl_handler,
1183                                              &ctrl_run_mode, NULL);
1184         asd->vfpp = v4l2_ctrl_new_custom(&asd->ctrl_handler,
1185                                          &ctrl_vfpp, NULL);
1186         asd->continuous_mode = v4l2_ctrl_new_custom(&asd->ctrl_handler,
1187                                &ctrl_continuous_mode, NULL);
1188         asd->continuous_viewfinder = v4l2_ctrl_new_custom(&asd->ctrl_handler,
1189                                      &ctrl_continuous_viewfinder,
1190                                      NULL);
1191         asd->continuous_raw_buffer_size =
1192             v4l2_ctrl_new_custom(&asd->ctrl_handler,
1193                                  &ctrl_continuous_raw_buffer_size,
1194                                  NULL);
1195
1196         asd->enable_raw_buffer_lock =
1197             v4l2_ctrl_new_custom(&asd->ctrl_handler,
1198                                  &ctrl_enable_raw_buffer_lock,
1199                                  NULL);
1200         asd->depth_mode =
1201             v4l2_ctrl_new_custom(&asd->ctrl_handler,
1202                                  &ctrl_depth_mode,
1203                                  NULL);
1204         asd->disable_dz =
1205             v4l2_ctrl_new_custom(&asd->ctrl_handler,
1206                                  &ctrl_disable_dz,
1207                                  NULL);
1208
1209         /* Make controls visible on subdev as well. */
1210         asd->subdev.ctrl_handler = &asd->ctrl_handler;
1211         spin_lock_init(&asd->raw_buffer_bitmap_lock);
1212         return asd->ctrl_handler.error;
1213 }
1214
1215 int atomisp_create_pads_links(struct atomisp_device *isp)
1216 {
1217         struct atomisp_sub_device *asd;
1218         int i, j, ret = 0;
1219
1220         isp->num_of_streams = 2;
1221         for (i = 0; i < ATOMISP_CAMERA_NR_PORTS; i++) {
1222                 for (j = 0; j < isp->num_of_streams; j++) {
1223                         ret =
1224                             media_create_pad_link(&isp->csi2_port[i].subdev.
1225                                                   entity, CSI2_PAD_SOURCE,
1226                                                   &isp->asd[j].subdev.entity,
1227                                                   ATOMISP_SUBDEV_PAD_SINK, 0);
1228                         if (ret < 0)
1229                                 return ret;
1230                 }
1231         }
1232         for (i = 0; i < isp->input_cnt - 2; i++) {
1233                 ret = media_create_pad_link(&isp->inputs[i].camera->entity, 0,
1234                                             &isp->csi2_port[isp->inputs[i].
1235                                                     port].subdev.entity,
1236                                             CSI2_PAD_SINK,
1237                                             MEDIA_LNK_FL_ENABLED |
1238                                             MEDIA_LNK_FL_IMMUTABLE);
1239                 if (ret < 0)
1240                         return ret;
1241         }
1242         for (i = 0; i < isp->num_of_streams; i++) {
1243                 asd = &isp->asd[i];
1244                 ret = media_create_pad_link(&asd->subdev.entity,
1245                                             ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW,
1246                                             &asd->video_out_preview.vdev.entity,
1247                                             0, 0);
1248                 if (ret < 0)
1249                         return ret;
1250                 ret = media_create_pad_link(&asd->subdev.entity,
1251                                             ATOMISP_SUBDEV_PAD_SOURCE_VF,
1252                                             &asd->video_out_vf.vdev.entity, 0,
1253                                             0);
1254                 if (ret < 0)
1255                         return ret;
1256                 ret = media_create_pad_link(&asd->subdev.entity,
1257                                             ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE,
1258                                             &asd->video_out_capture.vdev.entity,
1259                                             0, 0);
1260                 if (ret < 0)
1261                         return ret;
1262                 ret = media_create_pad_link(&asd->subdev.entity,
1263                                             ATOMISP_SUBDEV_PAD_SOURCE_VIDEO,
1264                                             &asd->video_out_video_capture.vdev.
1265                                             entity, 0, 0);
1266                 if (ret < 0)
1267                         return ret;
1268                 /*
1269                  * file input only supported on subdev0
1270                  * so do not create pad link for subdevs other then subdev0
1271                  */
1272                 if (asd->index)
1273                         return 0;
1274                 ret = media_create_pad_link(&asd->video_in.vdev.entity,
1275                                             0, &asd->subdev.entity,
1276                                             ATOMISP_SUBDEV_PAD_SINK, 0);
1277                 if (ret < 0)
1278                         return ret;
1279         }
1280         return 0;
1281 }
1282
1283 static void atomisp_subdev_cleanup_entities(struct atomisp_sub_device *asd)
1284 {
1285         v4l2_ctrl_handler_free(&asd->ctrl_handler);
1286
1287         media_entity_cleanup(&asd->subdev.entity);
1288 }
1289
1290 void atomisp_subdev_cleanup_pending_events(struct atomisp_sub_device *asd)
1291 {
1292         struct v4l2_fh *fh, *fh_tmp;
1293         struct v4l2_event event;
1294         unsigned int i, pending_event;
1295
1296         list_for_each_entry_safe(fh, fh_tmp,
1297                                  &asd->subdev.devnode->fh_list, list) {
1298                 pending_event = v4l2_event_pending(fh);
1299                 for (i = 0; i < pending_event; i++)
1300                         v4l2_event_dequeue(fh, &event, 1);
1301         }
1302 }
1303
1304 void atomisp_subdev_unregister_entities(struct atomisp_sub_device *asd)
1305 {
1306         atomisp_subdev_cleanup_entities(asd);
1307         v4l2_device_unregister_subdev(&asd->subdev);
1308         atomisp_video_unregister(&asd->video_in);
1309         atomisp_video_unregister(&asd->video_out_preview);
1310         atomisp_video_unregister(&asd->video_out_vf);
1311         atomisp_video_unregister(&asd->video_out_capture);
1312         atomisp_video_unregister(&asd->video_out_video_capture);
1313         atomisp_acc_unregister(&asd->video_acc);
1314 }
1315
1316 int atomisp_subdev_register_entities(struct atomisp_sub_device *asd,
1317                                      struct v4l2_device *vdev)
1318 {
1319         int ret;
1320         u32 device_caps;
1321
1322         /*
1323          * FIXME: check if all device caps are properly initialized.
1324          * Should any of those use V4L2_CAP_META_OUTPUT? Probably yes.
1325          */
1326
1327         device_caps = V4L2_CAP_VIDEO_CAPTURE |
1328                       V4L2_CAP_STREAMING;
1329
1330         /* Register the subdev and video node. */
1331
1332         ret = v4l2_device_register_subdev(vdev, &asd->subdev);
1333         if (ret < 0)
1334                 goto error;
1335
1336         asd->video_out_preview.vdev.v4l2_dev = vdev;
1337         asd->video_out_preview.vdev.device_caps = device_caps |
1338                                                   V4L2_CAP_VIDEO_OUTPUT;
1339         ret = video_register_device(&asd->video_out_preview.vdev,
1340                                     VFL_TYPE_VIDEO, -1);
1341         if (ret < 0)
1342                 goto error;
1343
1344         asd->video_out_capture.vdev.v4l2_dev = vdev;
1345         asd->video_out_capture.vdev.device_caps = device_caps |
1346                                                   V4L2_CAP_VIDEO_OUTPUT;
1347         ret = video_register_device(&asd->video_out_capture.vdev,
1348                                     VFL_TYPE_VIDEO, -1);
1349         if (ret < 0)
1350                 goto error;
1351
1352         asd->video_out_vf.vdev.v4l2_dev = vdev;
1353         asd->video_out_vf.vdev.device_caps = device_caps |
1354                                              V4L2_CAP_VIDEO_OUTPUT;
1355         ret = video_register_device(&asd->video_out_vf.vdev,
1356                                     VFL_TYPE_VIDEO, -1);
1357         if (ret < 0)
1358                 goto error;
1359
1360         asd->video_out_video_capture.vdev.v4l2_dev = vdev;
1361         asd->video_out_video_capture.vdev.device_caps = device_caps |
1362                                                         V4L2_CAP_VIDEO_OUTPUT;
1363         ret = video_register_device(&asd->video_out_video_capture.vdev,
1364                                     VFL_TYPE_VIDEO, -1);
1365         if (ret < 0)
1366                 goto error;
1367         asd->video_acc.vdev.v4l2_dev = vdev;
1368         asd->video_acc.vdev.device_caps = device_caps |
1369                                           V4L2_CAP_VIDEO_OUTPUT;
1370         ret = video_register_device(&asd->video_acc.vdev,
1371                                     VFL_TYPE_VIDEO, -1);
1372         if (ret < 0)
1373                 goto error;
1374
1375         /*
1376          * file input only supported on subdev0
1377          * so do not create video node for subdevs other then subdev0
1378          */
1379         if (asd->index)
1380                 return 0;
1381
1382         asd->video_in.vdev.v4l2_dev = vdev;
1383         asd->video_in.vdev.device_caps = device_caps |
1384                                           V4L2_CAP_VIDEO_CAPTURE;
1385         ret = video_register_device(&asd->video_in.vdev,
1386                                     VFL_TYPE_VIDEO, -1);
1387         if (ret < 0)
1388                 goto error;
1389
1390         return 0;
1391
1392 error:
1393         atomisp_subdev_unregister_entities(asd);
1394         return ret;
1395 }
1396
1397 /*
1398  * atomisp_subdev_init - ISP Subdevice  initialization.
1399  * @dev: Device pointer specific to the ATOM ISP.
1400  *
1401  * TODO: Get the initialisation values from platform data.
1402  *
1403  * Return 0 on success or a negative error code otherwise.
1404  */
1405 int atomisp_subdev_init(struct atomisp_device *isp)
1406 {
1407         struct atomisp_sub_device *asd;
1408         int i, ret = 0;
1409
1410         /*
1411          * CSS2.0 running ISP2400 support
1412          * multiple streams
1413          */
1414         isp->num_of_streams = 2;
1415         isp->asd = devm_kzalloc(isp->dev, sizeof(struct atomisp_sub_device) *
1416                                 isp->num_of_streams, GFP_KERNEL);
1417         if (!isp->asd)
1418                 return -ENOMEM;
1419         for (i = 0; i < isp->num_of_streams; i++) {
1420                 asd = &isp->asd[i];
1421                 spin_lock_init(&asd->lock);
1422                 asd->isp = isp;
1423                 isp_subdev_init_params(asd);
1424                 asd->index = i;
1425                 ret = isp_subdev_init_entities(asd);
1426                 if (ret < 0) {
1427                         atomisp_subdev_cleanup_entities(asd);
1428                         break;
1429                 }
1430         }
1431
1432         return ret;
1433 }