media: atomisp: Remove atomisp_sensor_start_stream()
[platform/kernel/linux-starfive.git] / drivers / staging / media / atomisp / pci / atomisp_ioctl.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  * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License version
11  * 2 as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  *
19  */
20
21 #include <linux/delay.h>
22 #include <linux/pci.h>
23
24 #include <media/v4l2-ioctl.h>
25 #include <media/v4l2-event.h>
26
27 #include "atomisp_cmd.h"
28 #include "atomisp_common.h"
29 #include "atomisp_fops.h"
30 #include "atomisp_internal.h"
31 #include "atomisp_ioctl.h"
32 #include "atomisp-regs.h"
33 #include "atomisp_compat.h"
34
35 #include "sh_css_hrt.h"
36
37 #include "gp_device.h"
38 #include "device_access.h"
39 #include "irq.h"
40
41 static const char *DRIVER = "atomisp";  /* max size 15 */
42 static const char *CARD = "ATOM ISP";   /* max size 31 */
43
44 /*
45  * FIXME: ISP should not know beforehand all CIDs supported by sensor.
46  * Instead, it needs to propagate to sensor unkonwn CIDs.
47  */
48 static struct v4l2_queryctrl ci_v4l2_controls[] = {
49         {
50                 .id = V4L2_CID_AUTO_WHITE_BALANCE,
51                 .type = V4L2_CTRL_TYPE_BOOLEAN,
52                 .name = "Automatic White Balance",
53                 .minimum = 0,
54                 .maximum = 1,
55                 .step = 1,
56                 .default_value = 0,
57         },
58         {
59                 .id = V4L2_CID_RED_BALANCE,
60                 .type = V4L2_CTRL_TYPE_INTEGER,
61                 .name = "Red Balance",
62                 .minimum = 0x00,
63                 .maximum = 0xff,
64                 .step = 1,
65                 .default_value = 0x00,
66         },
67         {
68                 .id = V4L2_CID_BLUE_BALANCE,
69                 .type = V4L2_CTRL_TYPE_INTEGER,
70                 .name = "Blue Balance",
71                 .minimum = 0x00,
72                 .maximum = 0xff,
73                 .step = 1,
74                 .default_value = 0x00,
75         },
76         {
77                 .id = V4L2_CID_GAMMA,
78                 .type = V4L2_CTRL_TYPE_INTEGER,
79                 .name = "Gamma",
80                 .minimum = 0x00,
81                 .maximum = 0xff,
82                 .step = 1,
83                 .default_value = 0x00,
84         },
85         {
86                 .id = V4L2_CID_POWER_LINE_FREQUENCY,
87                 .type = V4L2_CTRL_TYPE_MENU,
88                 .name = "Light frequency filter",
89                 .minimum = 1,
90                 .maximum = 2,
91                 .step = 1,
92                 .default_value = 1,
93         },
94         {
95                 .id = V4L2_CID_COLORFX,
96                 .type = V4L2_CTRL_TYPE_INTEGER,
97                 .name = "Image Color Effect",
98                 .minimum = 0,
99                 .maximum = 9,
100                 .step = 1,
101                 .default_value = 0,
102         },
103         {
104                 .id = V4L2_CID_COLORFX_CBCR,
105                 .type = V4L2_CTRL_TYPE_INTEGER,
106                 .name = "Image Color Effect CbCr",
107                 .minimum = 0,
108                 .maximum = 0xffff,
109                 .step = 1,
110                 .default_value = 0,
111         },
112         {
113                 .id = V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION,
114                 .type = V4L2_CTRL_TYPE_INTEGER,
115                 .name = "Bad Pixel Correction",
116                 .minimum = 0,
117                 .maximum = 1,
118                 .step = 1,
119                 .default_value = 0,
120         },
121         {
122                 .id = V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC,
123                 .type = V4L2_CTRL_TYPE_INTEGER,
124                 .name = "GDC/CAC",
125                 .minimum = 0,
126                 .maximum = 1,
127                 .step = 1,
128                 .default_value = 0,
129         },
130         {
131                 .id = V4L2_CID_ATOMISP_VIDEO_STABLIZATION,
132                 .type = V4L2_CTRL_TYPE_INTEGER,
133                 .name = "Video Stablization",
134                 .minimum = 0,
135                 .maximum = 1,
136                 .step = 1,
137                 .default_value = 0,
138         },
139         {
140                 .id = V4L2_CID_ATOMISP_FIXED_PATTERN_NR,
141                 .type = V4L2_CTRL_TYPE_INTEGER,
142                 .name = "Fixed Pattern Noise Reduction",
143                 .minimum = 0,
144                 .maximum = 1,
145                 .step = 1,
146                 .default_value = 0,
147         },
148         {
149                 .id = V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION,
150                 .type = V4L2_CTRL_TYPE_INTEGER,
151                 .name = "False Color Correction",
152                 .minimum = 0,
153                 .maximum = 1,
154                 .step = 1,
155                 .default_value = 0,
156         },
157         {
158                 .id = V4L2_CID_REQUEST_FLASH,
159                 .type = V4L2_CTRL_TYPE_INTEGER,
160                 .name = "Request flash frames",
161                 .minimum = 0,
162                 .maximum = 10,
163                 .step = 1,
164                 .default_value = 1,
165         },
166         {
167                 .id = V4L2_CID_ATOMISP_LOW_LIGHT,
168                 .type = V4L2_CTRL_TYPE_BOOLEAN,
169                 .name = "Low light mode",
170                 .minimum = 0,
171                 .maximum = 1,
172                 .step = 1,
173                 .default_value = 1,
174         },
175         {
176                 .id = V4L2_CID_2A_STATUS,
177                 .type = V4L2_CTRL_TYPE_BITMASK,
178                 .name = "AE and AWB status",
179                 .minimum = 0,
180                 .maximum = V4L2_2A_STATUS_AE_READY | V4L2_2A_STATUS_AWB_READY,
181                 .step = 1,
182                 .default_value = 0,
183         },
184         {
185                 .id = V4L2_CID_EXPOSURE,
186                 .type = V4L2_CTRL_TYPE_INTEGER,
187                 .name = "exposure",
188                 .minimum = -4,
189                 .maximum = 4,
190                 .step = 1,
191                 .default_value = 0,
192         },
193         {
194                 .id = V4L2_CID_EXPOSURE_ZONE_NUM,
195                 .type = V4L2_CTRL_TYPE_INTEGER,
196                 .name = "one-time exposure zone number",
197                 .minimum = 0x0,
198                 .maximum = 0xffff,
199                 .step = 1,
200                 .default_value = 0,
201         },
202         {
203                 .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
204                 .type = V4L2_CTRL_TYPE_INTEGER,
205                 .name = "Exposure auto priority",
206                 .minimum = V4L2_EXPOSURE_AUTO,
207                 .maximum = V4L2_EXPOSURE_APERTURE_PRIORITY,
208                 .step = 1,
209                 .default_value = V4L2_EXPOSURE_AUTO,
210         },
211         {
212                 .id = V4L2_CID_SCENE_MODE,
213                 .type = V4L2_CTRL_TYPE_INTEGER,
214                 .name = "scene mode",
215                 .minimum = 0,
216                 .maximum = 13,
217                 .step = 1,
218                 .default_value = 0,
219         },
220         {
221                 .id = V4L2_CID_ISO_SENSITIVITY,
222                 .type = V4L2_CTRL_TYPE_INTEGER,
223                 .name = "iso",
224                 .minimum = -4,
225                 .maximum = 4,
226                 .step = 1,
227                 .default_value = 0,
228         },
229         {
230                 .id = V4L2_CID_ISO_SENSITIVITY_AUTO,
231                 .type = V4L2_CTRL_TYPE_INTEGER,
232                 .name = "iso mode",
233                 .minimum = V4L2_ISO_SENSITIVITY_MANUAL,
234                 .maximum = V4L2_ISO_SENSITIVITY_AUTO,
235                 .step = 1,
236                 .default_value = V4L2_ISO_SENSITIVITY_AUTO,
237         },
238         {
239                 .id = V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
240                 .type = V4L2_CTRL_TYPE_INTEGER,
241                 .name = "white balance",
242                 .minimum = 0,
243                 .maximum = 9,
244                 .step = 1,
245                 .default_value = 0,
246         },
247         {
248                 .id = V4L2_CID_EXPOSURE_METERING,
249                 .type = V4L2_CTRL_TYPE_MENU,
250                 .name = "metering",
251                 .minimum = 0,
252                 .maximum = 3,
253                 .step = 1,
254                 .default_value = 1,
255         },
256         {
257                 .id = V4L2_CID_3A_LOCK,
258                 .type = V4L2_CTRL_TYPE_BITMASK,
259                 .name = "3a lock",
260                 .minimum = 0,
261                 .maximum = V4L2_LOCK_EXPOSURE | V4L2_LOCK_WHITE_BALANCE
262                 | V4L2_LOCK_FOCUS,
263                 .step = 1,
264                 .default_value = 0,
265         },
266         {
267                 .id = V4L2_CID_TEST_PATTERN,
268                 .type = V4L2_CTRL_TYPE_INTEGER,
269                 .name = "Test Pattern",
270                 .minimum = 0,
271                 .maximum = 0xffff,
272                 .step = 1,
273                 .default_value = 0,
274         },
275         {
276                 .id = V4L2_CID_TEST_PATTERN_COLOR_R,
277                 .type = V4L2_CTRL_TYPE_INTEGER,
278                 .name = "Test Pattern Solid Color R",
279                 .minimum = INT_MIN,
280                 .maximum = INT_MAX,
281                 .step = 1,
282                 .default_value = 0,
283         },
284         {
285                 .id = V4L2_CID_TEST_PATTERN_COLOR_GR,
286                 .type = V4L2_CTRL_TYPE_INTEGER,
287                 .name = "Test Pattern Solid Color GR",
288                 .minimum = INT_MIN,
289                 .maximum = INT_MAX,
290                 .step = 1,
291                 .default_value = 0,
292         },
293         {
294                 .id = V4L2_CID_TEST_PATTERN_COLOR_GB,
295                 .type = V4L2_CTRL_TYPE_INTEGER,
296                 .name = "Test Pattern Solid Color GB",
297                 .minimum = INT_MIN,
298                 .maximum = INT_MAX,
299                 .step = 1,
300                 .default_value = 0,
301         },
302         {
303                 .id = V4L2_CID_TEST_PATTERN_COLOR_B,
304                 .type = V4L2_CTRL_TYPE_INTEGER,
305                 .name = "Test Pattern Solid Color B",
306                 .minimum = INT_MIN,
307                 .maximum = INT_MAX,
308                 .step = 1,
309                 .default_value = 0,
310         },
311 };
312
313 static const u32 ctrls_num = ARRAY_SIZE(ci_v4l2_controls);
314
315 /*
316  * supported V4L2 fmts and resolutions
317  */
318 const struct atomisp_format_bridge atomisp_output_fmts[] = {
319         {
320                 .pixelformat = V4L2_PIX_FMT_YUV420,
321                 .depth = 12,
322                 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV420,
323                 .sh_fmt = IA_CSS_FRAME_FORMAT_YUV420,
324                 .description = "YUV420, planar",
325                 .planar = true
326         }, {
327                 .pixelformat = V4L2_PIX_FMT_YVU420,
328                 .depth = 12,
329                 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YVU420,
330                 .sh_fmt = IA_CSS_FRAME_FORMAT_YV12,
331                 .description = "YVU420, planar",
332                 .planar = true
333         }, {
334                 .pixelformat = V4L2_PIX_FMT_YUV422P,
335                 .depth = 16,
336                 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV422P,
337                 .sh_fmt = IA_CSS_FRAME_FORMAT_YUV422,
338                 .description = "YUV422, planar",
339                 .planar = true
340         }, {
341                 .pixelformat = V4L2_PIX_FMT_YUV444,
342                 .depth = 24,
343                 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV444,
344                 .sh_fmt = IA_CSS_FRAME_FORMAT_YUV444,
345                 .description = "YUV444"
346         }, {
347                 .pixelformat = V4L2_PIX_FMT_NV12,
348                 .depth = 12,
349                 .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV12,
350                 .sh_fmt = IA_CSS_FRAME_FORMAT_NV12,
351                 .description = "NV12, Y-plane, CbCr interleaved",
352                 .planar = true
353         }, {
354                 .pixelformat = V4L2_PIX_FMT_NV21,
355                 .depth = 12,
356                 .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV21,
357                 .sh_fmt = IA_CSS_FRAME_FORMAT_NV21,
358                 .description = "NV21, Y-plane, CbCr interleaved",
359                 .planar = true
360         }, {
361                 .pixelformat = V4L2_PIX_FMT_NV16,
362                 .depth = 16,
363                 .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV16,
364                 .sh_fmt = IA_CSS_FRAME_FORMAT_NV16,
365                 .description = "NV16, Y-plane, CbCr interleaved",
366                 .planar = true
367         }, {
368                 .pixelformat = V4L2_PIX_FMT_YUYV,
369                 .depth = 16,
370                 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUYV,
371                 .sh_fmt = IA_CSS_FRAME_FORMAT_YUYV,
372                 .description = "YUYV, interleaved"
373         }, {
374                 .pixelformat = V4L2_PIX_FMT_UYVY,
375                 .depth = 16,
376                 .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
377                 .sh_fmt = IA_CSS_FRAME_FORMAT_UYVY,
378                 .description = "UYVY, interleaved"
379         }, { /* This one is for parallel sensors! DO NOT USE! */
380                 .pixelformat = V4L2_PIX_FMT_UYVY,
381                 .depth = 16,
382                 .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
383                 .sh_fmt = IA_CSS_FRAME_FORMAT_UYVY,
384                 .description = "UYVY, interleaved"
385         }, {
386                 .pixelformat = V4L2_PIX_FMT_SBGGR16,
387                 .depth = 16,
388                 .mbus_code = V4L2_MBUS_FMT_CUSTOM_SBGGR16,
389                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
390                 .description = "Bayer 16"
391         }, {
392                 .pixelformat = V4L2_PIX_FMT_SBGGR8,
393                 .depth = 8,
394                 .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
395                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
396                 .description = "Bayer 8"
397         }, {
398                 .pixelformat = V4L2_PIX_FMT_SGBRG8,
399                 .depth = 8,
400                 .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
401                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
402                 .description = "Bayer 8"
403         }, {
404                 .pixelformat = V4L2_PIX_FMT_SGRBG8,
405                 .depth = 8,
406                 .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
407                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
408                 .description = "Bayer 8"
409         }, {
410                 .pixelformat = V4L2_PIX_FMT_SRGGB8,
411                 .depth = 8,
412                 .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
413                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
414                 .description = "Bayer 8"
415         }, {
416                 .pixelformat = V4L2_PIX_FMT_SBGGR10,
417                 .depth = 16,
418                 .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
419                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
420                 .description = "Bayer 10"
421         }, {
422                 .pixelformat = V4L2_PIX_FMT_SGBRG10,
423                 .depth = 16,
424                 .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
425                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
426                 .description = "Bayer 10"
427         }, {
428                 .pixelformat = V4L2_PIX_FMT_SGRBG10,
429                 .depth = 16,
430                 .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
431                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
432                 .description = "Bayer 10"
433         }, {
434                 .pixelformat = V4L2_PIX_FMT_SRGGB10,
435                 .depth = 16,
436                 .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
437                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
438                 .description = "Bayer 10"
439         }, {
440                 .pixelformat = V4L2_PIX_FMT_SBGGR12,
441                 .depth = 16,
442                 .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
443                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
444                 .description = "Bayer 12"
445         }, {
446                 .pixelformat = V4L2_PIX_FMT_SGBRG12,
447                 .depth = 16,
448                 .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
449                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
450                 .description = "Bayer 12"
451         }, {
452                 .pixelformat = V4L2_PIX_FMT_SGRBG12,
453                 .depth = 16,
454                 .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
455                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
456                 .description = "Bayer 12"
457         }, {
458                 .pixelformat = V4L2_PIX_FMT_SRGGB12,
459                 .depth = 16,
460                 .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
461                 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
462                 .description = "Bayer 12"
463         }, {
464                 .pixelformat = V4L2_PIX_FMT_RGB32,
465                 .depth = 32,
466                 .mbus_code = V4L2_MBUS_FMT_CUSTOM_RGB32,
467                 .sh_fmt = IA_CSS_FRAME_FORMAT_RGBA888,
468                 .description = "32 RGB 8-8-8-8"
469         }, {
470                 .pixelformat = V4L2_PIX_FMT_RGB565,
471                 .depth = 16,
472                 .mbus_code = MEDIA_BUS_FMT_BGR565_2X8_LE,
473                 .sh_fmt = IA_CSS_FRAME_FORMAT_RGB565,
474                 .description = "16 RGB 5-6-5"
475 #if 0
476         }, {
477                 .pixelformat = V4L2_PIX_FMT_JPEG,
478                 .depth = 8,
479                 .mbus_code = MEDIA_BUS_FMT_JPEG_1X8,
480                 .sh_fmt = IA_CSS_FRAME_FORMAT_BINARY_8,
481                 .description = "JPEG"
482         }, {
483                 /* This is a custom format being used by M10MO to send the RAW data */
484                 .pixelformat = V4L2_PIX_FMT_CUSTOM_M10MO_RAW,
485                 .depth = 8,
486                 .mbus_code = V4L2_MBUS_FMT_CUSTOM_M10MO_RAW,
487                 .sh_fmt = IA_CSS_FRAME_FORMAT_BINARY_8,
488                 .description = "Custom RAW for M10MO"
489 #endif
490         },
491 };
492
493 const struct atomisp_format_bridge *
494 atomisp_get_format_bridge(unsigned int pixelformat)
495 {
496         unsigned int i;
497
498         for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
499                 if (atomisp_output_fmts[i].pixelformat == pixelformat)
500                         return &atomisp_output_fmts[i];
501         }
502
503         return NULL;
504 }
505
506 const struct atomisp_format_bridge *
507 atomisp_get_format_bridge_from_mbus(u32 mbus_code)
508 {
509         unsigned int i;
510
511         for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
512                 if (mbus_code == atomisp_output_fmts[i].mbus_code)
513                         return &atomisp_output_fmts[i];
514         }
515
516         return NULL;
517 }
518
519 int atomisp_pipe_check(struct atomisp_video_pipe *pipe, bool settings_change)
520 {
521         lockdep_assert_held(&pipe->isp->mutex);
522
523         if (pipe->isp->isp_fatal_error)
524                 return -EIO;
525
526         if (settings_change && vb2_is_busy(&pipe->vb_queue)) {
527                 dev_err(pipe->isp->dev, "Set fmt/input IOCTL while streaming\n");
528                 return -EBUSY;
529         }
530
531         switch (pipe->asd->streaming) {
532         case ATOMISP_DEVICE_STREAMING_DISABLED:
533                 break;
534         case ATOMISP_DEVICE_STREAMING_ENABLED:
535                 if (settings_change) {
536                         dev_err(pipe->isp->dev, "Set fmt/input IOCTL while streaming\n");
537                         return -EBUSY;
538                 }
539                 break;
540         case ATOMISP_DEVICE_STREAMING_STOPPING:
541                 dev_err(pipe->isp->dev, "IOCTL issued while stopping\n");
542                 return -EBUSY;
543         default:
544                 return -EINVAL;
545         }
546
547         return 0;
548 }
549
550 /*
551  * v4l2 ioctls
552  * return ISP capabilities
553  */
554 static int atomisp_querycap(struct file *file, void *fh,
555                             struct v4l2_capability *cap)
556 {
557         struct video_device *vdev = video_devdata(file);
558         struct atomisp_device *isp = video_get_drvdata(vdev);
559
560         strscpy(cap->driver, DRIVER, sizeof(cap->driver));
561         strscpy(cap->card, CARD, sizeof(cap->card));
562         snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", dev_name(isp->dev));
563
564         return 0;
565 }
566
567 /*
568  * enum input are used to check primary/secondary camera
569  */
570 static int atomisp_enum_input(struct file *file, void *fh,
571                               struct v4l2_input *input)
572 {
573         struct video_device *vdev = video_devdata(file);
574         struct atomisp_device *isp = video_get_drvdata(vdev);
575         int index = input->index;
576         struct v4l2_subdev *motor;
577
578         if (index >= isp->input_cnt)
579                 return -EINVAL;
580
581         if (!isp->inputs[index].camera)
582                 return -EINVAL;
583
584         memset(input, 0, sizeof(struct v4l2_input));
585         strscpy(input->name, isp->inputs[index].camera->name,
586                 sizeof(input->name));
587
588         /*
589          * HACK: append actuator's name to sensor's
590          * As currently userspace can't talk directly to subdev nodes, this
591          * ioctl is the only way to enum inputs + possible external actuators
592          * for 3A tuning purpose.
593          */
594         if (!IS_ISP2401)
595                 motor = isp->inputs[index].motor;
596         else
597                 motor = isp->motor;
598
599         if (motor && strlen(motor->name) > 0) {
600                 const int cur_len = strlen(input->name);
601                 const int max_size = sizeof(input->name) - cur_len - 1;
602
603                 if (max_size > 1) {
604                         input->name[cur_len] = '+';
605                         strscpy(&input->name[cur_len + 1],
606                                 motor->name, max_size);
607                 }
608         }
609
610         input->type = V4L2_INPUT_TYPE_CAMERA;
611         input->index = index;
612         input->reserved[0] = isp->inputs[index].type;
613         input->reserved[1] = isp->inputs[index].port;
614
615         return 0;
616 }
617
618 static unsigned int
619 atomisp_subdev_streaming_count(struct atomisp_sub_device *asd)
620 {
621         return vb2_start_streaming_called(&asd->video_out.vb_queue);
622 }
623
624 unsigned int atomisp_streaming_count(struct atomisp_device *isp)
625 {
626         return isp->asd.streaming == ATOMISP_DEVICE_STREAMING_ENABLED;
627 }
628
629 /*
630  * get input are used to get current primary/secondary camera
631  */
632 static int atomisp_g_input(struct file *file, void *fh, unsigned int *input)
633 {
634         struct video_device *vdev = video_devdata(file);
635         struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
636
637         *input = asd->input_curr;
638         return 0;
639 }
640
641 static int atomisp_s_fmt_cap(struct file *file, void *fh,
642                              struct v4l2_format *f)
643 {
644         struct video_device *vdev = video_devdata(file);
645
646         return atomisp_set_fmt(vdev, f);
647 }
648
649 /*
650  * set input are used to set current primary/secondary camera
651  */
652 static int atomisp_s_input(struct file *file, void *fh, unsigned int input)
653 {
654         struct video_device *vdev = video_devdata(file);
655         struct atomisp_device *isp = video_get_drvdata(vdev);
656         struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
657         struct atomisp_sub_device *asd = pipe->asd;
658         struct v4l2_subdev *camera = NULL;
659         struct v4l2_subdev *motor;
660         int ret;
661
662         ret = atomisp_pipe_check(pipe, true);
663         if (ret)
664                 return ret;
665
666         if (input >= ATOM_ISP_MAX_INPUTS || input >= isp->input_cnt) {
667                 dev_dbg(isp->dev, "input_cnt: %d\n", isp->input_cnt);
668                 return -EINVAL;
669         }
670
671         camera = isp->inputs[input].camera;
672         if (!camera) {
673                 dev_err(isp->dev, "%s, no camera\n", __func__);
674                 return -EINVAL;
675         }
676
677         /* power off the current owned sensor, as it is not used this time */
678         if (isp->inputs[asd->input_curr].asd == asd &&
679             asd->input_curr != input) {
680                 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
681                                        core, s_power, 0);
682                 if (ret && ret != -ENOIOCTLCMD)
683                         dev_warn(isp->dev,
684                                  "Failed to power-off sensor\n");
685                 /* clear the asd field to show this camera is not used */
686                 isp->inputs[asd->input_curr].asd = NULL;
687         }
688
689         /* powe on the new sensor */
690         ret = v4l2_subdev_call(isp->inputs[input].camera, core, s_power, 1);
691         if (ret && ret != -ENOIOCTLCMD) {
692                 dev_err(isp->dev, "Failed to power-on sensor\n");
693                 return ret;
694         }
695         /*
696          * Some sensor driver resets the run mode during power-on, thus force
697          * update the run mode to sensor after power-on.
698          */
699         atomisp_update_run_mode(asd);
700
701         /* select operating sensor */
702         ret = v4l2_subdev_call(isp->inputs[input].camera, video, s_routing,
703                                0, isp->inputs[input].sensor_index, 0);
704         if (ret && (ret != -ENOIOCTLCMD)) {
705                 dev_err(isp->dev, "Failed to select sensor\n");
706                 return ret;
707         }
708
709         if (!IS_ISP2401) {
710                 motor = isp->inputs[input].motor;
711         } else {
712                 motor = isp->motor;
713                 if (motor)
714                         ret = v4l2_subdev_call(motor, core, s_power, 1);
715         }
716
717         if (motor)
718                 ret = v4l2_subdev_call(motor, core, init, 1);
719
720         asd->input_curr = input;
721         /* mark this camera is used by the current stream */
722         isp->inputs[input].asd = asd;
723
724         return 0;
725 }
726
727 static int atomisp_enum_framesizes(struct file *file, void *priv,
728                                    struct v4l2_frmsizeenum *fsize)
729 {
730         struct video_device *vdev = video_devdata(file);
731         struct atomisp_device *isp = video_get_drvdata(vdev);
732         struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
733         struct v4l2_subdev_frame_size_enum fse = {
734                 .index = fsize->index,
735                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
736         };
737         int ret;
738
739         ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
740                                pad, enum_frame_size, NULL, &fse);
741         if (ret)
742                 return ret;
743
744         fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
745         fsize->discrete.width = fse.max_width - pad_w;
746         fsize->discrete.height = fse.max_height - pad_h;
747
748         return 0;
749 }
750
751 static int atomisp_enum_frameintervals(struct file *file, void *priv,
752                                        struct v4l2_frmivalenum *fival)
753 {
754         struct video_device *vdev = video_devdata(file);
755         struct atomisp_device *isp = video_get_drvdata(vdev);
756         struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
757         struct v4l2_subdev_frame_interval_enum fie = {
758                 .code   = atomisp_in_fmt_conv[0].code,
759                 .index = fival->index,
760                 .width = fival->width,
761                 .height = fival->height,
762                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
763         };
764         int ret;
765
766         ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
767                                pad, enum_frame_interval, NULL,
768                                &fie);
769         if (ret)
770                 return ret;
771
772         fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
773         fival->discrete = fie.interval;
774
775         return ret;
776 }
777
778 static int atomisp_enum_fmt_cap(struct file *file, void *fh,
779                                 struct v4l2_fmtdesc *f)
780 {
781         struct video_device *vdev = video_devdata(file);
782         struct atomisp_device *isp = video_get_drvdata(vdev);
783         struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
784         struct v4l2_subdev_mbus_code_enum code = {
785                 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
786         };
787         const struct atomisp_format_bridge *format;
788         struct v4l2_subdev *camera;
789         unsigned int i, fi = 0;
790         int rval;
791
792         camera = isp->inputs[asd->input_curr].camera;
793         if(!camera) {
794                 dev_err(isp->dev, "%s(): camera is NULL, device is %s\n",
795                         __func__, vdev->name);
796                 return -EINVAL;
797         }
798
799         rval = v4l2_subdev_call(camera, pad, enum_mbus_code, NULL, &code);
800         if (rval == -ENOIOCTLCMD) {
801                 dev_warn(isp->dev,
802                          "enum_mbus_code pad op not supported by %s. Please fix your sensor driver!\n",
803                          camera->name);
804         }
805
806         if (rval)
807                 return rval;
808
809         for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
810                 format = &atomisp_output_fmts[i];
811
812                 /*
813                  * Is the atomisp-supported format is valid for the
814                  * sensor (configuration)? If not, skip it.
815                  *
816                  * FIXME: fix the pipeline to allow sensor format too.
817                  */
818                 if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW)
819                         continue;
820
821                 /* Found a match. Now let's pick f->index'th one. */
822                 if (fi < f->index) {
823                         fi++;
824                         continue;
825                 }
826
827                 strscpy(f->description, format->description,
828                         sizeof(f->description));
829                 f->pixelformat = format->pixelformat;
830                 return 0;
831         }
832
833         return -EINVAL;
834 }
835
836 static int atomisp_adjust_fmt(struct v4l2_format *f)
837 {
838         const struct atomisp_format_bridge *format_bridge;
839         u32 padded_width;
840
841         format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
842         /* Currently, raw formats are broken!!! */
843         if (!format_bridge || format_bridge->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) {
844                 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
845
846                 format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
847                 if (!format_bridge)
848                         return -EINVAL;
849         }
850
851         padded_width = f->fmt.pix.width + pad_w;
852
853         if (format_bridge->planar) {
854                 f->fmt.pix.bytesperline = padded_width;
855                 f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height *
856                                                   DIV_ROUND_UP(format_bridge->depth *
857                                                   padded_width, 8));
858         } else {
859                 f->fmt.pix.bytesperline = DIV_ROUND_UP(format_bridge->depth *
860                                                       padded_width, 8);
861                 f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * f->fmt.pix.bytesperline);
862         }
863
864         if (f->fmt.pix.field == V4L2_FIELD_ANY)
865                 f->fmt.pix.field = V4L2_FIELD_NONE;
866
867         /*
868          * FIXME: do we need to setup this differently, depending on the
869          * sensor or the pipeline?
870          */
871         f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
872         f->fmt.pix.ycbcr_enc = V4L2_YCBCR_ENC_709;
873         f->fmt.pix.xfer_func = V4L2_XFER_FUNC_709;
874
875         f->fmt.pix.width -= pad_w;
876         f->fmt.pix.height -= pad_h;
877
878         return 0;
879 }
880
881 /* This function looks up the closest available resolution. */
882 static int atomisp_try_fmt_cap(struct file *file, void *fh,
883                                struct v4l2_format *f)
884 {
885         struct video_device *vdev = video_devdata(file);
886         u32 pixfmt = f->fmt.pix.pixelformat;
887         int ret;
888
889         /*
890          * atomisp_try_fmt() gived results with padding included, note
891          * (this gets removed again by the atomisp_adjust_fmt() call below.
892          */
893         f->fmt.pix.width += pad_w;
894         f->fmt.pix.height += pad_h;
895
896         ret = atomisp_try_fmt(vdev, &f->fmt.pix);
897         if (ret)
898                 return ret;
899
900         /*
901          * atomisp_try_fmt() replaces pixelformat with the sensors native
902          * format, restore the actual format requested by userspace.
903          */
904         f->fmt.pix.pixelformat = pixfmt;
905
906         return atomisp_adjust_fmt(f);
907 }
908
909 static int atomisp_g_fmt_cap(struct file *file, void *fh,
910                              struct v4l2_format *f)
911 {
912         struct video_device *vdev = video_devdata(file);
913         struct atomisp_video_pipe *pipe;
914
915         pipe = atomisp_to_video_pipe(vdev);
916
917         f->fmt.pix = pipe->pix;
918
919         /* If s_fmt was issued, just return whatever is was previouly set */
920         if (f->fmt.pix.sizeimage)
921                 return 0;
922
923         f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
924         f->fmt.pix.width = 10000;
925         f->fmt.pix.height = 10000;
926
927         return atomisp_try_fmt_cap(file, fh, f);
928 }
929
930 int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd,
931                                 uint16_t stream_id)
932 {
933         struct atomisp_device *isp = asd->isp;
934         struct atomisp_s3a_buf *s3a_buf = NULL, *_s3a_buf;
935         struct atomisp_dis_buf *dis_buf = NULL, *_dis_buf;
936         struct atomisp_metadata_buf *md_buf = NULL, *_md_buf;
937         int count;
938         struct ia_css_dvs_grid_info *dvs_grid_info =
939             atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
940         unsigned int i;
941
942         if (list_empty(&asd->s3a_stats) &&
943             asd->params.curr_grid_info.s3a_grid.enable) {
944                 count = ATOMISP_CSS_Q_DEPTH +
945                         ATOMISP_S3A_BUF_QUEUE_DEPTH_FOR_HAL;
946                 dev_dbg(isp->dev, "allocating %d 3a buffers\n", count);
947                 while (count--) {
948                         s3a_buf = kzalloc(sizeof(struct atomisp_s3a_buf), GFP_KERNEL);
949                         if (!s3a_buf)
950                                 goto error;
951
952                         if (atomisp_css_allocate_stat_buffers(
953                                 asd, stream_id, s3a_buf, NULL, NULL)) {
954                                 kfree(s3a_buf);
955                                 goto error;
956                         }
957
958                         list_add_tail(&s3a_buf->list, &asd->s3a_stats);
959                 }
960         }
961
962         if (list_empty(&asd->dis_stats) && dvs_grid_info &&
963             dvs_grid_info->enable) {
964                 count = ATOMISP_CSS_Q_DEPTH + 1;
965                 dev_dbg(isp->dev, "allocating %d dis buffers\n", count);
966                 while (count--) {
967                         dis_buf = kzalloc(sizeof(struct atomisp_dis_buf), GFP_KERNEL);
968                         if (!dis_buf)
969                                 goto error;
970                         if (atomisp_css_allocate_stat_buffers(
971                                 asd, stream_id, NULL, dis_buf, NULL)) {
972                                 kfree(dis_buf);
973                                 goto error;
974                         }
975
976                         list_add_tail(&dis_buf->list, &asd->dis_stats);
977                 }
978         }
979
980         for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
981                 if (list_empty(&asd->metadata[i]) &&
982                     list_empty(&asd->metadata_ready[i]) &&
983                     list_empty(&asd->metadata_in_css[i])) {
984                         count = ATOMISP_CSS_Q_DEPTH +
985                                 ATOMISP_METADATA_QUEUE_DEPTH_FOR_HAL;
986                         dev_dbg(isp->dev, "allocating %d metadata buffers for type %d\n",
987                                 count, i);
988                         while (count--) {
989                                 md_buf = kzalloc(sizeof(struct atomisp_metadata_buf),
990                                                  GFP_KERNEL);
991                                 if (!md_buf)
992                                         goto error;
993
994                                 if (atomisp_css_allocate_stat_buffers(
995                                         asd, stream_id, NULL, NULL, md_buf)) {
996                                         kfree(md_buf);
997                                         goto error;
998                                 }
999                                 list_add_tail(&md_buf->list, &asd->metadata[i]);
1000                         }
1001                 }
1002         }
1003         return 0;
1004
1005 error:
1006         dev_err(isp->dev, "failed to allocate statistics buffers\n");
1007
1008         list_for_each_entry_safe(dis_buf, _dis_buf, &asd->dis_stats, list) {
1009                 atomisp_css_free_dis_buffer(dis_buf);
1010                 list_del(&dis_buf->list);
1011                 kfree(dis_buf);
1012         }
1013
1014         list_for_each_entry_safe(s3a_buf, _s3a_buf, &asd->s3a_stats, list) {
1015                 atomisp_css_free_3a_buffer(s3a_buf);
1016                 list_del(&s3a_buf->list);
1017                 kfree(s3a_buf);
1018         }
1019
1020         for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
1021                 list_for_each_entry_safe(md_buf, _md_buf, &asd->metadata[i],
1022                                          list) {
1023                         atomisp_css_free_metadata_buffer(md_buf);
1024                         list_del(&md_buf->list);
1025                         kfree(md_buf);
1026                 }
1027         }
1028         return -ENOMEM;
1029 }
1030
1031 /*
1032  * FIXME the abuse of buf->reserved2 in the qbuf and dqbuf wrappers comes from
1033  * the original atomisp buffer handling and should be replaced with proper V4L2
1034  * per frame parameters use.
1035  *
1036  * Once this is fixed these wrappers can be removed, replacing them with direct
1037  * calls to vb2_ioctl_[d]qbuf().
1038  */
1039 static int atomisp_qbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer *buf)
1040 {
1041         struct video_device *vdev = video_devdata(file);
1042         struct atomisp_device *isp = video_get_drvdata(vdev);
1043         struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1044
1045         if (buf->index >= vdev->queue->num_buffers)
1046                 return -EINVAL;
1047
1048         if (buf->reserved2 & ATOMISP_BUFFER_HAS_PER_FRAME_SETTING) {
1049                 /* this buffer will have a per-frame parameter */
1050                 pipe->frame_request_config_id[buf->index] = buf->reserved2 &
1051                         ~ATOMISP_BUFFER_HAS_PER_FRAME_SETTING;
1052                 dev_dbg(isp->dev,
1053                         "This buffer requires per_frame setting which has isp_config_id %d\n",
1054                         pipe->frame_request_config_id[buf->index]);
1055         } else {
1056                 pipe->frame_request_config_id[buf->index] = 0;
1057         }
1058
1059         return vb2_ioctl_qbuf(file, fh, buf);
1060 }
1061
1062 static int atomisp_dqbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer *buf)
1063 {
1064         struct video_device *vdev = video_devdata(file);
1065         struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1066         struct atomisp_sub_device *asd = pipe->asd;
1067         struct atomisp_device *isp = video_get_drvdata(vdev);
1068         struct ia_css_frame *frame;
1069         struct vb2_buffer *vb;
1070         int ret;
1071
1072         ret = vb2_ioctl_dqbuf(file, fh, buf);
1073         if (ret)
1074                 return ret;
1075
1076         vb = pipe->vb_queue.bufs[buf->index];
1077         frame = vb_to_frame(vb);
1078
1079         buf->reserved = asd->frame_status[buf->index];
1080
1081         /*
1082          * Hack:
1083          * Currently frame_status in the enum type which takes no more lower
1084          * 8 bit.
1085          * use bit[31:16] for exp_id as it is only in the range of 1~255
1086          */
1087         buf->reserved &= 0x0000ffff;
1088         if (!(buf->flags & V4L2_BUF_FLAG_ERROR))
1089                 buf->reserved |= frame->exp_id;
1090         buf->reserved2 = pipe->frame_config_id[buf->index];
1091
1092         dev_dbg(isp->dev,
1093                 "dqbuf buffer %d (%s) with exp_id %d, isp_config_id %d\n",
1094                 buf->index, vdev->name, buf->reserved >> 16, buf->reserved2);
1095         return 0;
1096 }
1097
1098 enum ia_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device *asd)
1099 {
1100         /*
1101          * Disable vf_pp and run CSS in video mode. This allows using ISP
1102          * scaling but it has one frame delay due to CSS internal buffering.
1103          */
1104         if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER)
1105                 return IA_CSS_PIPE_ID_VIDEO;
1106
1107         /*
1108          * Disable vf_pp and run CSS in still capture mode. In this mode
1109          * CSS does not cause extra latency with buffering, but scaling
1110          * is not available.
1111          */
1112         if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT)
1113                 return IA_CSS_PIPE_ID_CAPTURE;
1114
1115         switch (asd->run_mode->val) {
1116         case ATOMISP_RUN_MODE_PREVIEW:
1117                 return IA_CSS_PIPE_ID_PREVIEW;
1118         case ATOMISP_RUN_MODE_VIDEO:
1119                 return IA_CSS_PIPE_ID_VIDEO;
1120         case ATOMISP_RUN_MODE_STILL_CAPTURE:
1121         default:
1122                 return IA_CSS_PIPE_ID_CAPTURE;
1123         }
1124 }
1125
1126 /* Input system HW workaround */
1127 /* Input system address translation corrupts burst during */
1128 /* invalidate. SW workaround for this is to set burst length */
1129 /* manually to 128 in case of 13MPx snapshot and to 1 otherwise. */
1130 static void atomisp_dma_burst_len_cfg(struct atomisp_sub_device *asd)
1131 {
1132         struct v4l2_mbus_framefmt *sink;
1133
1134         sink = atomisp_subdev_get_ffmt(&asd->subdev, NULL,
1135                                        V4L2_SUBDEV_FORMAT_ACTIVE,
1136                                        ATOMISP_SUBDEV_PAD_SINK);
1137
1138         if (sink->width * sink->height >= 4096 * 3072)
1139                 atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x7F);
1140         else
1141                 atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x00);
1142 }
1143
1144 int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count)
1145 {
1146         struct atomisp_video_pipe *pipe = vq_to_pipe(vq);
1147         struct atomisp_sub_device *asd = pipe->asd;
1148         struct atomisp_device *isp = asd->isp;
1149         struct pci_dev *pdev = to_pci_dev(isp->dev);
1150         enum ia_css_pipe_id css_pipe_id;
1151         unsigned long irqflags;
1152         int ret;
1153
1154         dev_dbg(isp->dev, "Start stream\n");
1155
1156         mutex_lock(&isp->mutex);
1157
1158         ret = atomisp_pipe_check(pipe, false);
1159         if (ret)
1160                 goto out_unlock;
1161
1162         /* Input system HW workaround */
1163         atomisp_dma_burst_len_cfg(asd);
1164
1165         if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) {
1166                 atomisp_qbuffers_to_css(asd);
1167                 goto start_sensor;
1168         }
1169
1170         css_pipe_id = atomisp_get_css_pipe_id(asd);
1171
1172         /* Invalidate caches. FIXME: should flush only necessary buffers */
1173         wbinvd();
1174
1175         if (asd->params.css_update_params_needed) {
1176                 atomisp_apply_css_parameters(asd, &asd->params.css_param);
1177                 if (asd->params.css_param.update_flag.dz_config)
1178                         asd->params.config.dz_config = &asd->params.css_param.dz_config;
1179                 atomisp_css_update_isp_params(asd);
1180                 asd->params.css_update_params_needed = false;
1181                 memset(&asd->params.css_param.update_flag, 0,
1182                        sizeof(struct atomisp_parameters));
1183         }
1184         asd->params.dvs_6axis = NULL;
1185
1186         ret = atomisp_css_start(asd, css_pipe_id, false);
1187         if (ret) {
1188                 atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_QUEUED, true);
1189                 goto out_unlock;
1190         }
1191
1192         spin_lock_irqsave(&isp->lock, irqflags);
1193         asd->streaming = ATOMISP_DEVICE_STREAMING_ENABLED;
1194         spin_unlock_irqrestore(&isp->lock, irqflags);
1195         atomic_set(&asd->sof_count, -1);
1196         atomic_set(&asd->sequence, -1);
1197         atomic_set(&asd->sequence_temp, -1);
1198
1199         asd->params.dis_proj_data_valid = false;
1200         asd->latest_preview_exp_id = 0;
1201         asd->postview_exp_id = 1;
1202         asd->preview_exp_id = 1;
1203
1204         /* handle per_frame_setting parameter and buffers */
1205         atomisp_handle_parameter_and_buffer(pipe);
1206
1207         atomisp_qbuffers_to_css(asd);
1208
1209 start_sensor:
1210         if (isp->flash) {
1211                 asd->params.num_flash_frames = 0;
1212                 asd->params.flash_state = ATOMISP_FLASH_IDLE;
1213                 atomisp_setup_flash(asd);
1214         }
1215
1216         atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF,
1217                                atomisp_css_valid_sof(isp));
1218         atomisp_csi2_configure(asd);
1219         /*
1220          * set freq to max when streaming count > 1 which indicate
1221          * dual camera would run
1222          */
1223         if (atomisp_streaming_count(isp) > 1) {
1224                 if (atomisp_freq_scaling(isp,
1225                                          ATOMISP_DFS_MODE_MAX, false) < 0)
1226                         dev_dbg(isp->dev, "DFS max mode failed!\n");
1227         } else {
1228                 if (atomisp_freq_scaling(isp,
1229                                          ATOMISP_DFS_MODE_AUTO, false) < 0)
1230                         dev_dbg(isp->dev, "DFS auto mode failed!\n");
1231         }
1232
1233         /* Enable the CSI interface on ANN B0/K0 */
1234         if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
1235                                             ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) {
1236                 pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL,
1237                                       isp->saved_regs.csi_control | MRFLD_PCI_CSI_CONTROL_CSI_READY);
1238         }
1239
1240         /* stream on the sensor */
1241         ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
1242                                video, s_stream, 1);
1243         if (ret) {
1244                 spin_lock_irqsave(&isp->lock, irqflags);
1245                 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
1246                 spin_unlock_irqrestore(&isp->lock, irqflags);
1247                 ret = -EINVAL;
1248                 goto out_unlock;
1249         }
1250
1251 out_unlock:
1252         mutex_unlock(&isp->mutex);
1253         return ret;
1254 }
1255
1256 void atomisp_stop_streaming(struct vb2_queue *vq)
1257 {
1258         struct atomisp_video_pipe *pipe = vq_to_pipe(vq);
1259         struct atomisp_sub_device *asd = pipe->asd;
1260         struct atomisp_device *isp = asd->isp;
1261         struct pci_dev *pdev = to_pci_dev(isp->dev);
1262         enum ia_css_pipe_id css_pipe_id;
1263         bool recreate_stream = false;
1264         bool first_streamoff = false;
1265         unsigned long flags;
1266         int ret;
1267
1268         dev_dbg(isp->dev, "Stop stream\n");
1269
1270         mutex_lock(&isp->mutex);
1271         /*
1272          * There is no guarantee that the buffers queued to / owned by the ISP
1273          * will properly be returned to the queue when stopping. Set a flag to
1274          * avoid new buffers getting queued and then wait for all the current
1275          * buffers to finish.
1276          */
1277         pipe->stopping = true;
1278         mutex_unlock(&isp->mutex);
1279         /* wait max 1 second */
1280         ret = wait_event_timeout(pipe->vb_queue.done_wq,
1281                                  atomisp_buffers_in_css(pipe) == 0, HZ);
1282         mutex_lock(&isp->mutex);
1283         pipe->stopping = false;
1284         if (ret == 0)
1285                 dev_warn(isp->dev, "Warning timeout waiting for CSS to return buffers\n");
1286
1287         if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED)
1288                 first_streamoff = true;
1289
1290         spin_lock_irqsave(&isp->lock, flags);
1291         if (atomisp_subdev_streaming_count(asd) == 1)
1292                 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
1293         else
1294                 asd->streaming = ATOMISP_DEVICE_STREAMING_STOPPING;
1295         spin_unlock_irqrestore(&isp->lock, flags);
1296
1297         if (!first_streamoff)
1298                 goto stopsensor;
1299
1300         atomisp_clear_css_buffer_counters(asd);
1301         atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false);
1302
1303         css_pipe_id = atomisp_get_css_pipe_id(asd);
1304         atomisp_css_stop(asd, css_pipe_id, false);
1305
1306         atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_ERROR, true);
1307
1308         atomisp_subdev_cleanup_pending_events(asd);
1309 stopsensor:
1310         ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
1311                                video, s_stream, 0);
1312
1313         if (isp->flash) {
1314                 asd->params.num_flash_frames = 0;
1315                 asd->params.flash_state = ATOMISP_FLASH_IDLE;
1316         }
1317
1318         /* if other streams are running, isp should not be powered off */
1319         if (atomisp_streaming_count(isp)) {
1320                 atomisp_css_flush(isp);
1321                 goto out_unlock;
1322         }
1323
1324         /* Disable the CSI interface on ANN B0/K0 */
1325         if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
1326                                             ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) {
1327                 pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL,
1328                                       isp->saved_regs.csi_control & ~MRFLD_PCI_CSI_CONTROL_CSI_READY);
1329         }
1330
1331         if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false))
1332                 dev_warn(isp->dev, "DFS failed.\n");
1333         /*
1334          * ISP work around, need to reset isp
1335          * Is it correct time to reset ISP when first node does streamoff?
1336          *
1337          * It is possible that the other asd stream is in the stage
1338          * that v4l2_setfmt is just get called on it, which will
1339          * create css stream on that stream. But at this point, there
1340          * is no way to destroy the css stream created on that stream.
1341          *
1342          * So force stream destroy here.
1343          */
1344         if (isp->asd.stream_prepared) {
1345                 atomisp_destroy_pipes_stream_force(&isp->asd);
1346                 recreate_stream = true;
1347         }
1348
1349         /* disable  PUNIT/ISP acknowlede/handshake - SRSE=3 */
1350         pci_write_config_dword(pdev, PCI_I_CONTROL,
1351                                isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK);
1352         dev_err(isp->dev, "atomisp_reset");
1353         atomisp_reset(isp);
1354
1355         if (recreate_stream) {
1356                 int ret2;
1357
1358                 ret2 = atomisp_create_pipes_stream(&isp->asd);
1359                 if (ret2) {
1360                         dev_err(isp->dev, "%s error re-creating streams: %d\n", __func__, ret2);
1361                         if (!ret)
1362                                 ret = ret2;
1363                 }
1364         }
1365
1366 out_unlock:
1367         mutex_unlock(&isp->mutex);
1368 }
1369
1370 /*
1371  * To get the current value of a control.
1372  * applications initialize the id field of a struct v4l2_control and
1373  * call this ioctl with a pointer to this structure
1374  */
1375 static int atomisp_g_ctrl(struct file *file, void *fh,
1376                           struct v4l2_control *control)
1377 {
1378         struct video_device *vdev = video_devdata(file);
1379         struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
1380         struct atomisp_device *isp = video_get_drvdata(vdev);
1381         int i, ret = -EINVAL;
1382
1383         for (i = 0; i < ctrls_num; i++) {
1384                 if (ci_v4l2_controls[i].id == control->id) {
1385                         ret = 0;
1386                         break;
1387                 }
1388         }
1389
1390         if (ret)
1391                 return ret;
1392
1393         switch (control->id) {
1394         case V4L2_CID_IRIS_ABSOLUTE:
1395         case V4L2_CID_EXPOSURE_ABSOLUTE:
1396         case V4L2_CID_2A_STATUS:
1397         case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
1398         case V4L2_CID_EXPOSURE:
1399         case V4L2_CID_EXPOSURE_AUTO:
1400         case V4L2_CID_SCENE_MODE:
1401         case V4L2_CID_ISO_SENSITIVITY:
1402         case V4L2_CID_ISO_SENSITIVITY_AUTO:
1403         case V4L2_CID_CONTRAST:
1404         case V4L2_CID_SATURATION:
1405         case V4L2_CID_SHARPNESS:
1406         case V4L2_CID_3A_LOCK:
1407         case V4L2_CID_EXPOSURE_ZONE_NUM:
1408         case V4L2_CID_TEST_PATTERN:
1409         case V4L2_CID_TEST_PATTERN_COLOR_R:
1410         case V4L2_CID_TEST_PATTERN_COLOR_GR:
1411         case V4L2_CID_TEST_PATTERN_COLOR_GB:
1412         case V4L2_CID_TEST_PATTERN_COLOR_B:
1413                 return v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->
1414                                    ctrl_handler, control);
1415         case V4L2_CID_COLORFX:
1416                 ret = atomisp_color_effect(asd, 0, &control->value);
1417                 break;
1418         case V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION:
1419                 ret = atomisp_bad_pixel(asd, 0, &control->value);
1420                 break;
1421         case V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC:
1422                 ret = atomisp_gdc_cac(asd, 0, &control->value);
1423                 break;
1424         case V4L2_CID_ATOMISP_VIDEO_STABLIZATION:
1425                 ret = atomisp_video_stable(asd, 0, &control->value);
1426                 break;
1427         case V4L2_CID_ATOMISP_FIXED_PATTERN_NR:
1428                 ret = atomisp_fixed_pattern(asd, 0, &control->value);
1429                 break;
1430         case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION:
1431                 ret = atomisp_false_color(asd, 0, &control->value);
1432                 break;
1433         case V4L2_CID_ATOMISP_LOW_LIGHT:
1434                 ret = atomisp_low_light(asd, 0, &control->value);
1435                 break;
1436         default:
1437                 ret = -EINVAL;
1438                 break;
1439         }
1440
1441         return ret;
1442 }
1443
1444 /*
1445  * To change the value of a control.
1446  * applications initialize the id and value fields of a struct v4l2_control
1447  * and call this ioctl.
1448  */
1449 static int atomisp_s_ctrl(struct file *file, void *fh,
1450                           struct v4l2_control *control)
1451 {
1452         struct video_device *vdev = video_devdata(file);
1453         struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
1454         struct atomisp_device *isp = video_get_drvdata(vdev);
1455         int i, ret = -EINVAL;
1456
1457         for (i = 0; i < ctrls_num; i++) {
1458                 if (ci_v4l2_controls[i].id == control->id) {
1459                         ret = 0;
1460                         break;
1461                 }
1462         }
1463
1464         if (ret)
1465                 return ret;
1466
1467         switch (control->id) {
1468         case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
1469         case V4L2_CID_EXPOSURE:
1470         case V4L2_CID_EXPOSURE_AUTO:
1471         case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
1472         case V4L2_CID_SCENE_MODE:
1473         case V4L2_CID_ISO_SENSITIVITY:
1474         case V4L2_CID_ISO_SENSITIVITY_AUTO:
1475         case V4L2_CID_POWER_LINE_FREQUENCY:
1476         case V4L2_CID_EXPOSURE_METERING:
1477         case V4L2_CID_CONTRAST:
1478         case V4L2_CID_SATURATION:
1479         case V4L2_CID_SHARPNESS:
1480         case V4L2_CID_3A_LOCK:
1481         case V4L2_CID_COLORFX_CBCR:
1482         case V4L2_CID_TEST_PATTERN:
1483         case V4L2_CID_TEST_PATTERN_COLOR_R:
1484         case V4L2_CID_TEST_PATTERN_COLOR_GR:
1485         case V4L2_CID_TEST_PATTERN_COLOR_GB:
1486         case V4L2_CID_TEST_PATTERN_COLOR_B:
1487                 return v4l2_s_ctrl(NULL,
1488                                    isp->inputs[asd->input_curr].camera->
1489                                    ctrl_handler, control);
1490         case V4L2_CID_COLORFX:
1491                 ret = atomisp_color_effect(asd, 1, &control->value);
1492                 break;
1493         case V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION:
1494                 ret = atomisp_bad_pixel(asd, 1, &control->value);
1495                 break;
1496         case V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC:
1497                 ret = atomisp_gdc_cac(asd, 1, &control->value);
1498                 break;
1499         case V4L2_CID_ATOMISP_VIDEO_STABLIZATION:
1500                 ret = atomisp_video_stable(asd, 1, &control->value);
1501                 break;
1502         case V4L2_CID_ATOMISP_FIXED_PATTERN_NR:
1503                 ret = atomisp_fixed_pattern(asd, 1, &control->value);
1504                 break;
1505         case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION:
1506                 ret = atomisp_false_color(asd, 1, &control->value);
1507                 break;
1508         case V4L2_CID_REQUEST_FLASH:
1509                 ret = atomisp_flash_enable(asd, control->value);
1510                 break;
1511         case V4L2_CID_ATOMISP_LOW_LIGHT:
1512                 ret = atomisp_low_light(asd, 1, &control->value);
1513                 break;
1514         default:
1515                 ret = -EINVAL;
1516                 break;
1517         }
1518         return ret;
1519 }
1520
1521 /*
1522  * To query the attributes of a control.
1523  * applications set the id field of a struct v4l2_queryctrl and call the
1524  * this ioctl with a pointer to this structure. The driver fills
1525  * the rest of the structure.
1526  */
1527 static int atomisp_queryctl(struct file *file, void *fh,
1528                             struct v4l2_queryctrl *qc)
1529 {
1530         int i, ret = -EINVAL;
1531         struct video_device *vdev = video_devdata(file);
1532         struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
1533         struct atomisp_device *isp = video_get_drvdata(vdev);
1534
1535         switch (qc->id) {
1536         case V4L2_CID_FOCUS_ABSOLUTE:
1537         case V4L2_CID_FOCUS_RELATIVE:
1538         case V4L2_CID_FOCUS_STATUS:
1539                 if (!IS_ISP2401) {
1540                         return v4l2_queryctrl(isp->inputs[asd->input_curr].camera->
1541                                             ctrl_handler, qc);
1542                 }
1543                 /* ISP2401 */
1544                 if (isp->motor)
1545                         return v4l2_queryctrl(isp->motor->ctrl_handler, qc);
1546                 else
1547                         return v4l2_queryctrl(isp->inputs[asd->input_curr].
1548                                               camera->ctrl_handler, qc);
1549         }
1550
1551         if (qc->id & V4L2_CTRL_FLAG_NEXT_CTRL)
1552                 return ret;
1553
1554         for (i = 0; i < ctrls_num; i++) {
1555                 if (ci_v4l2_controls[i].id == qc->id) {
1556                         memcpy(qc, &ci_v4l2_controls[i],
1557                                sizeof(struct v4l2_queryctrl));
1558                         qc->reserved[0] = 0;
1559                         ret = 0;
1560                         break;
1561                 }
1562         }
1563         if (ret != 0)
1564                 qc->flags = V4L2_CTRL_FLAG_DISABLED;
1565
1566         return ret;
1567 }
1568
1569 static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh,
1570                                       struct v4l2_ext_controls *c)
1571 {
1572         struct video_device *vdev = video_devdata(file);
1573         struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
1574         struct atomisp_device *isp = video_get_drvdata(vdev);
1575         struct v4l2_subdev *motor;
1576         struct v4l2_control ctrl;
1577         int i;
1578         int ret = 0;
1579
1580         if (!IS_ISP2401)
1581                 motor = isp->inputs[asd->input_curr].motor;
1582         else
1583                 motor = isp->motor;
1584
1585         for (i = 0; i < c->count; i++) {
1586                 ctrl.id = c->controls[i].id;
1587                 ctrl.value = c->controls[i].value;
1588                 switch (ctrl.id) {
1589                 case V4L2_CID_EXPOSURE_ABSOLUTE:
1590                 case V4L2_CID_EXPOSURE_AUTO:
1591                 case V4L2_CID_IRIS_ABSOLUTE:
1592                 case V4L2_CID_3A_LOCK:
1593                 case V4L2_CID_TEST_PATTERN:
1594                 case V4L2_CID_TEST_PATTERN_COLOR_R:
1595                 case V4L2_CID_TEST_PATTERN_COLOR_GR:
1596                 case V4L2_CID_TEST_PATTERN_COLOR_GB:
1597                 case V4L2_CID_TEST_PATTERN_COLOR_B:
1598                         /*
1599                          * Exposure related control will be handled by sensor
1600                          * driver
1601                          */
1602                         ret =
1603                             v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->
1604                                         ctrl_handler, &ctrl);
1605                         break;
1606                 case V4L2_CID_FOCUS_ABSOLUTE:
1607                 case V4L2_CID_FOCUS_RELATIVE:
1608                 case V4L2_CID_FOCUS_STATUS:
1609                 case V4L2_CID_FOCUS_AUTO:
1610                         if (motor)
1611                                 ret = v4l2_g_ctrl(motor->ctrl_handler, &ctrl);
1612                         break;
1613                 case V4L2_CID_FLASH_STATUS:
1614                 case V4L2_CID_FLASH_INTENSITY:
1615                 case V4L2_CID_FLASH_TORCH_INTENSITY:
1616                 case V4L2_CID_FLASH_INDICATOR_INTENSITY:
1617                 case V4L2_CID_FLASH_TIMEOUT:
1618                 case V4L2_CID_FLASH_STROBE:
1619                 case V4L2_CID_FLASH_MODE:
1620                 case V4L2_CID_FLASH_STATUS_REGISTER:
1621                         if (isp->flash)
1622                                 ret =
1623                                     v4l2_g_ctrl(isp->flash->ctrl_handler,
1624                                                 &ctrl);
1625                         break;
1626                 case V4L2_CID_ZOOM_ABSOLUTE:
1627                         ret = atomisp_digital_zoom(asd, 0, &ctrl.value);
1628                         break;
1629                 case V4L2_CID_G_SKIP_FRAMES:
1630                         ret = v4l2_subdev_call(
1631                                   isp->inputs[asd->input_curr].camera,
1632                                   sensor, g_skip_frames, (u32 *)&ctrl.value);
1633                         break;
1634                 default:
1635                         ret = -EINVAL;
1636                 }
1637
1638                 if (ret) {
1639                         c->error_idx = i;
1640                         break;
1641                 }
1642                 c->controls[i].value = ctrl.value;
1643         }
1644         return ret;
1645 }
1646
1647 /* This ioctl allows the application to get multiple controls by class */
1648 static int atomisp_g_ext_ctrls(struct file *file, void *fh,
1649                                struct v4l2_ext_controls *c)
1650 {
1651         struct v4l2_control ctrl;
1652         int i, ret = 0;
1653
1654         /*
1655          * input_lock is not need for the Camera related IOCTLs
1656          * The input_lock downgrade the FPS of 3A
1657          */
1658         ret = atomisp_camera_g_ext_ctrls(file, fh, c);
1659         if (ret != -EINVAL)
1660                 return ret;
1661
1662         for (i = 0; i < c->count; i++) {
1663                 ctrl.id = c->controls[i].id;
1664                 ctrl.value = c->controls[i].value;
1665                 ret = atomisp_g_ctrl(file, fh, &ctrl);
1666                 c->controls[i].value = ctrl.value;
1667                 if (ret) {
1668                         c->error_idx = i;
1669                         break;
1670                 }
1671         }
1672         return ret;
1673 }
1674
1675 static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh,
1676                                       struct v4l2_ext_controls *c)
1677 {
1678         struct video_device *vdev = video_devdata(file);
1679         struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
1680         struct atomisp_device *isp = video_get_drvdata(vdev);
1681         struct v4l2_subdev *motor;
1682         struct v4l2_control ctrl;
1683         int i;
1684         int ret = 0;
1685
1686         if (!IS_ISP2401)
1687                 motor = isp->inputs[asd->input_curr].motor;
1688         else
1689                 motor = isp->motor;
1690
1691         for (i = 0; i < c->count; i++) {
1692                 struct v4l2_ctrl *ctr;
1693
1694                 ctrl.id = c->controls[i].id;
1695                 ctrl.value = c->controls[i].value;
1696                 switch (ctrl.id) {
1697                 case V4L2_CID_EXPOSURE_ABSOLUTE:
1698                 case V4L2_CID_EXPOSURE_AUTO:
1699                 case V4L2_CID_EXPOSURE_METERING:
1700                 case V4L2_CID_IRIS_ABSOLUTE:
1701                 case V4L2_CID_VCM_TIMING:
1702                 case V4L2_CID_VCM_SLEW:
1703                 case V4L2_CID_3A_LOCK:
1704                 case V4L2_CID_TEST_PATTERN:
1705                 case V4L2_CID_TEST_PATTERN_COLOR_R:
1706                 case V4L2_CID_TEST_PATTERN_COLOR_GR:
1707                 case V4L2_CID_TEST_PATTERN_COLOR_GB:
1708                 case V4L2_CID_TEST_PATTERN_COLOR_B:
1709                         ret = v4l2_s_ctrl(NULL,
1710                                           isp->inputs[asd->input_curr].camera->
1711                                           ctrl_handler, &ctrl);
1712                         break;
1713                 case V4L2_CID_FOCUS_ABSOLUTE:
1714                 case V4L2_CID_FOCUS_RELATIVE:
1715                 case V4L2_CID_FOCUS_STATUS:
1716                 case V4L2_CID_FOCUS_AUTO:
1717                         if (motor)
1718                                 ret = v4l2_s_ctrl(NULL, motor->ctrl_handler,
1719                                                   &ctrl);
1720                         else
1721                                 ret = v4l2_s_ctrl(NULL,
1722                                                   isp->inputs[asd->input_curr].
1723                                                   camera->ctrl_handler, &ctrl);
1724                         break;
1725                 case V4L2_CID_FLASH_STATUS:
1726                 case V4L2_CID_FLASH_INTENSITY:
1727                 case V4L2_CID_FLASH_TORCH_INTENSITY:
1728                 case V4L2_CID_FLASH_INDICATOR_INTENSITY:
1729                 case V4L2_CID_FLASH_TIMEOUT:
1730                 case V4L2_CID_FLASH_STROBE:
1731                 case V4L2_CID_FLASH_MODE:
1732                 case V4L2_CID_FLASH_STATUS_REGISTER:
1733                         if (isp->flash) {
1734                                 ret =
1735                                     v4l2_s_ctrl(NULL, isp->flash->ctrl_handler,
1736                                                 &ctrl);
1737                                 /*
1738                                  * When flash mode is changed we need to reset
1739                                  * flash state
1740                                  */
1741                                 if (ctrl.id == V4L2_CID_FLASH_MODE) {
1742                                         asd->params.flash_state =
1743                                             ATOMISP_FLASH_IDLE;
1744                                         asd->params.num_flash_frames = 0;
1745                                 }
1746                         }
1747                         break;
1748                 case V4L2_CID_ZOOM_ABSOLUTE:
1749                         ret = atomisp_digital_zoom(asd, 1, &ctrl.value);
1750                         break;
1751                 default:
1752                         ctr = v4l2_ctrl_find(&asd->ctrl_handler, ctrl.id);
1753                         if (ctr)
1754                                 ret = v4l2_ctrl_s_ctrl(ctr, ctrl.value);
1755                         else
1756                                 ret = -EINVAL;
1757                 }
1758
1759                 if (ret) {
1760                         c->error_idx = i;
1761                         break;
1762                 }
1763                 c->controls[i].value = ctrl.value;
1764         }
1765         return ret;
1766 }
1767
1768 /* This ioctl allows the application to set multiple controls by class */
1769 static int atomisp_s_ext_ctrls(struct file *file, void *fh,
1770                                struct v4l2_ext_controls *c)
1771 {
1772         struct v4l2_control ctrl;
1773         int i, ret = 0;
1774
1775         /*
1776          * input_lock is not need for the Camera related IOCTLs
1777          * The input_lock downgrade the FPS of 3A
1778          */
1779         ret = atomisp_camera_s_ext_ctrls(file, fh, c);
1780         if (ret != -EINVAL)
1781                 return ret;
1782
1783         for (i = 0; i < c->count; i++) {
1784                 ctrl.id = c->controls[i].id;
1785                 ctrl.value = c->controls[i].value;
1786                 ret = atomisp_s_ctrl(file, fh, &ctrl);
1787                 c->controls[i].value = ctrl.value;
1788                 if (ret) {
1789                         c->error_idx = i;
1790                         break;
1791                 }
1792         }
1793         return ret;
1794 }
1795
1796 /*
1797  * vidioc_g/s_param are used to switch isp running mode
1798  */
1799 static int atomisp_g_parm(struct file *file, void *fh,
1800                           struct v4l2_streamparm *parm)
1801 {
1802         struct video_device *vdev = video_devdata(file);
1803         struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
1804         struct atomisp_device *isp = video_get_drvdata(vdev);
1805
1806         if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1807                 dev_err(isp->dev, "unsupported v4l2 buf type\n");
1808                 return -EINVAL;
1809         }
1810
1811         parm->parm.capture.capturemode = asd->run_mode->val;
1812
1813         return 0;
1814 }
1815
1816 static int atomisp_s_parm(struct file *file, void *fh,
1817                           struct v4l2_streamparm *parm)
1818 {
1819         struct video_device *vdev = video_devdata(file);
1820         struct atomisp_device *isp = video_get_drvdata(vdev);
1821         struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
1822         int mode;
1823         int rval;
1824         int fps;
1825
1826         if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1827                 dev_err(isp->dev, "unsupported v4l2 buf type\n");
1828                 return -EINVAL;
1829         }
1830
1831         asd->high_speed_mode = false;
1832         switch (parm->parm.capture.capturemode) {
1833         case CI_MODE_NONE: {
1834                 struct v4l2_subdev_frame_interval fi = {0};
1835
1836                 fi.interval = parm->parm.capture.timeperframe;
1837
1838                 rval = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
1839                                         video, s_frame_interval, &fi);
1840                 if (!rval)
1841                         parm->parm.capture.timeperframe = fi.interval;
1842
1843                 if (fi.interval.numerator != 0) {
1844                         fps = fi.interval.denominator / fi.interval.numerator;
1845                         if (fps > 30)
1846                                 asd->high_speed_mode = true;
1847                 }
1848
1849                 return rval == -ENOIOCTLCMD ? 0 : rval;
1850         }
1851         case CI_MODE_VIDEO:
1852                 mode = ATOMISP_RUN_MODE_VIDEO;
1853                 break;
1854         case CI_MODE_STILL_CAPTURE:
1855                 mode = ATOMISP_RUN_MODE_STILL_CAPTURE;
1856                 break;
1857         case CI_MODE_PREVIEW:
1858                 mode = ATOMISP_RUN_MODE_PREVIEW;
1859                 break;
1860         default:
1861                 return -EINVAL;
1862         }
1863
1864         rval = v4l2_ctrl_s_ctrl(asd->run_mode, mode);
1865
1866         return rval == -ENOIOCTLCMD ? 0 : rval;
1867 }
1868
1869 static long atomisp_vidioc_default(struct file *file, void *fh,
1870                                    bool valid_prio, unsigned int cmd, void *arg)
1871 {
1872         struct video_device *vdev = video_devdata(file);
1873         struct atomisp_device *isp = video_get_drvdata(vdev);
1874         struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
1875         struct v4l2_subdev *motor;
1876         int err;
1877
1878         if (!IS_ISP2401)
1879                 motor = isp->inputs[asd->input_curr].motor;
1880         else
1881                 motor = isp->motor;
1882
1883         switch (cmd) {
1884         case ATOMISP_IOC_S_SENSOR_RUNMODE:
1885                 if (IS_ISP2401)
1886                         err = atomisp_set_sensor_runmode(asd, arg);
1887                 else
1888                         err = -EINVAL;
1889                 break;
1890
1891         case ATOMISP_IOC_G_XNR:
1892                 err = atomisp_xnr(asd, 0, arg);
1893                 break;
1894
1895         case ATOMISP_IOC_S_XNR:
1896                 err = atomisp_xnr(asd, 1, arg);
1897                 break;
1898
1899         case ATOMISP_IOC_G_NR:
1900                 err = atomisp_nr(asd, 0, arg);
1901                 break;
1902
1903         case ATOMISP_IOC_S_NR:
1904                 err = atomisp_nr(asd, 1, arg);
1905                 break;
1906
1907         case ATOMISP_IOC_G_TNR:
1908                 err = atomisp_tnr(asd, 0, arg);
1909                 break;
1910
1911         case ATOMISP_IOC_S_TNR:
1912                 err = atomisp_tnr(asd, 1, arg);
1913                 break;
1914
1915         case ATOMISP_IOC_G_BLACK_LEVEL_COMP:
1916                 err = atomisp_black_level(asd, 0, arg);
1917                 break;
1918
1919         case ATOMISP_IOC_S_BLACK_LEVEL_COMP:
1920                 err = atomisp_black_level(asd, 1, arg);
1921                 break;
1922
1923         case ATOMISP_IOC_G_EE:
1924                 err = atomisp_ee(asd, 0, arg);
1925                 break;
1926
1927         case ATOMISP_IOC_S_EE:
1928                 err = atomisp_ee(asd, 1, arg);
1929                 break;
1930
1931         case ATOMISP_IOC_G_DIS_STAT:
1932                 err = atomisp_get_dis_stat(asd, arg);
1933                 break;
1934
1935         case ATOMISP_IOC_G_DVS2_BQ_RESOLUTIONS:
1936                 err = atomisp_get_dvs2_bq_resolutions(asd, arg);
1937                 break;
1938
1939         case ATOMISP_IOC_S_DIS_COEFS:
1940                 err = atomisp_css_cp_dvs2_coefs(asd, arg,
1941                                                 &asd->params.css_param, true);
1942                 if (!err && arg)
1943                         asd->params.css_update_params_needed = true;
1944                 break;
1945
1946         case ATOMISP_IOC_S_DIS_VECTOR:
1947                 err = atomisp_cp_dvs_6axis_config(asd, arg,
1948                                                   &asd->params.css_param, true);
1949                 if (!err && arg)
1950                         asd->params.css_update_params_needed = true;
1951                 break;
1952
1953         case ATOMISP_IOC_G_ISP_PARM:
1954                 err = atomisp_param(asd, 0, arg);
1955                 break;
1956
1957         case ATOMISP_IOC_S_ISP_PARM:
1958                 err = atomisp_param(asd, 1, arg);
1959                 break;
1960
1961         case ATOMISP_IOC_G_3A_STAT:
1962                 err = atomisp_3a_stat(asd, 0, arg);
1963                 break;
1964
1965         case ATOMISP_IOC_G_ISP_GAMMA:
1966                 err = atomisp_gamma(asd, 0, arg);
1967                 break;
1968
1969         case ATOMISP_IOC_S_ISP_GAMMA:
1970                 err = atomisp_gamma(asd, 1, arg);
1971                 break;
1972
1973         case ATOMISP_IOC_G_ISP_GDC_TAB:
1974                 err = atomisp_gdc_cac_table(asd, 0, arg);
1975                 break;
1976
1977         case ATOMISP_IOC_S_ISP_GDC_TAB:
1978                 err = atomisp_gdc_cac_table(asd, 1, arg);
1979                 break;
1980
1981         case ATOMISP_IOC_G_ISP_MACC:
1982                 err = atomisp_macc_table(asd, 0, arg);
1983                 break;
1984
1985         case ATOMISP_IOC_S_ISP_MACC:
1986                 err = atomisp_macc_table(asd, 1, arg);
1987                 break;
1988
1989         case ATOMISP_IOC_G_ISP_BAD_PIXEL_DETECTION:
1990                 err = atomisp_bad_pixel_param(asd, 0, arg);
1991                 break;
1992
1993         case ATOMISP_IOC_S_ISP_BAD_PIXEL_DETECTION:
1994                 err = atomisp_bad_pixel_param(asd, 1, arg);
1995                 break;
1996
1997         case ATOMISP_IOC_G_ISP_FALSE_COLOR_CORRECTION:
1998                 err = atomisp_false_color_param(asd, 0, arg);
1999                 break;
2000
2001         case ATOMISP_IOC_S_ISP_FALSE_COLOR_CORRECTION:
2002                 err = atomisp_false_color_param(asd, 1, arg);
2003                 break;
2004
2005         case ATOMISP_IOC_G_ISP_CTC:
2006                 err = atomisp_ctc(asd, 0, arg);
2007                 break;
2008
2009         case ATOMISP_IOC_S_ISP_CTC:
2010                 err = atomisp_ctc(asd, 1, arg);
2011                 break;
2012
2013         case ATOMISP_IOC_G_ISP_WHITE_BALANCE:
2014                 err = atomisp_white_balance_param(asd, 0, arg);
2015                 break;
2016
2017         case ATOMISP_IOC_S_ISP_WHITE_BALANCE:
2018                 err = atomisp_white_balance_param(asd, 1, arg);
2019                 break;
2020
2021         case ATOMISP_IOC_G_3A_CONFIG:
2022                 err = atomisp_3a_config_param(asd, 0, arg);
2023                 break;
2024
2025         case ATOMISP_IOC_S_3A_CONFIG:
2026                 err = atomisp_3a_config_param(asd, 1, arg);
2027                 break;
2028
2029         case ATOMISP_IOC_S_ISP_FPN_TABLE:
2030                 err = atomisp_fixed_pattern_table(asd, arg);
2031                 break;
2032
2033         case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
2034                 if (motor)
2035                         err = v4l2_subdev_call(motor, core, ioctl, cmd, arg);
2036                 else
2037                         err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2038                                                core, ioctl, cmd, arg);
2039                 break;
2040
2041         case ATOMISP_IOC_S_EXPOSURE:
2042         case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
2043         case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
2044         case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO:
2045         case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE:
2046         case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE:
2047         case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT:
2048                 err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2049                                        core, ioctl, cmd, arg);
2050                 break;
2051         case ATOMISP_IOC_G_UPDATE_EXPOSURE:
2052                 if (IS_ISP2401)
2053                         err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2054                                                core, ioctl, cmd, arg);
2055                 else
2056                         err = -EINVAL;
2057                 break;
2058
2059         case ATOMISP_IOC_S_ISP_SHD_TAB:
2060                 err = atomisp_set_shading_table(asd, arg);
2061                 break;
2062
2063         case ATOMISP_IOC_G_ISP_GAMMA_CORRECTION:
2064                 err = atomisp_gamma_correction(asd, 0, arg);
2065                 break;
2066
2067         case ATOMISP_IOC_S_ISP_GAMMA_CORRECTION:
2068                 err = atomisp_gamma_correction(asd, 1, arg);
2069                 break;
2070
2071         case ATOMISP_IOC_S_PARAMETERS:
2072                 err = atomisp_set_parameters(vdev, arg);
2073                 break;
2074
2075         case ATOMISP_IOC_G_METADATA:
2076                 err = atomisp_get_metadata(asd, 0, arg);
2077                 break;
2078         case ATOMISP_IOC_G_METADATA_BY_TYPE:
2079                 err = atomisp_get_metadata_by_type(asd, 0, arg);
2080                 break;
2081         case ATOMISP_IOC_EXT_ISP_CTRL:
2082                 err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2083                                        core, ioctl, cmd, arg);
2084                 break;
2085         case ATOMISP_IOC_EXP_ID_UNLOCK:
2086                 err = atomisp_exp_id_unlock(asd, arg);
2087                 break;
2088         case ATOMISP_IOC_EXP_ID_CAPTURE:
2089                 err = atomisp_exp_id_capture(asd, arg);
2090                 break;
2091         case ATOMISP_IOC_S_ENABLE_DZ_CAPT_PIPE:
2092                 err = atomisp_enable_dz_capt_pipe(asd, arg);
2093                 break;
2094         case ATOMISP_IOC_G_FORMATS_CONFIG:
2095                 err = atomisp_formats(asd, 0, arg);
2096                 break;
2097
2098         case ATOMISP_IOC_S_FORMATS_CONFIG:
2099                 err = atomisp_formats(asd, 1, arg);
2100                 break;
2101         case ATOMISP_IOC_S_EXPOSURE_WINDOW:
2102                 err = atomisp_s_ae_window(asd, arg);
2103                 break;
2104         case ATOMISP_IOC_INJECT_A_FAKE_EVENT:
2105                 err = atomisp_inject_a_fake_event(asd, arg);
2106                 break;
2107         case ATOMISP_IOC_G_INVALID_FRAME_NUM:
2108                 err = atomisp_get_invalid_frame_num(vdev, arg);
2109                 break;
2110         case ATOMISP_IOC_S_ARRAY_RESOLUTION:
2111                 err = atomisp_set_array_res(asd, arg);
2112                 break;
2113         default:
2114                 err = -EINVAL;
2115                 break;
2116         }
2117
2118         return err;
2119 }
2120
2121 const struct v4l2_ioctl_ops atomisp_ioctl_ops = {
2122         .vidioc_querycap = atomisp_querycap,
2123         .vidioc_enum_input = atomisp_enum_input,
2124         .vidioc_g_input = atomisp_g_input,
2125         .vidioc_s_input = atomisp_s_input,
2126         .vidioc_queryctrl = atomisp_queryctl,
2127         .vidioc_s_ctrl = atomisp_s_ctrl,
2128         .vidioc_g_ctrl = atomisp_g_ctrl,
2129         .vidioc_s_ext_ctrls = atomisp_s_ext_ctrls,
2130         .vidioc_g_ext_ctrls = atomisp_g_ext_ctrls,
2131         .vidioc_enum_framesizes   = atomisp_enum_framesizes,
2132         .vidioc_enum_frameintervals = atomisp_enum_frameintervals,
2133         .vidioc_enum_fmt_vid_cap = atomisp_enum_fmt_cap,
2134         .vidioc_try_fmt_vid_cap = atomisp_try_fmt_cap,
2135         .vidioc_g_fmt_vid_cap = atomisp_g_fmt_cap,
2136         .vidioc_s_fmt_vid_cap = atomisp_s_fmt_cap,
2137         .vidioc_reqbufs = vb2_ioctl_reqbufs,
2138         .vidioc_querybuf = vb2_ioctl_querybuf,
2139         .vidioc_qbuf = atomisp_qbuf_wrapper,
2140         .vidioc_dqbuf = atomisp_dqbuf_wrapper,
2141         .vidioc_streamon = vb2_ioctl_streamon,
2142         .vidioc_streamoff = vb2_ioctl_streamoff,
2143         .vidioc_default = atomisp_vidioc_default,
2144         .vidioc_s_parm = atomisp_s_parm,
2145         .vidioc_g_parm = atomisp_g_parm,
2146 };