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