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