1 // SPDX-License-Identifier: GPL-2.0
3 * Support for Medifield PNW Camera Imaging ISP subsystem.
5 * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
7 * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
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.
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.
21 #include <linux/delay.h>
22 #include <linux/pci.h>
24 #include <media/v4l2-ioctl.h>
25 #include <media/v4l2-event.h>
26 #include <media/videobuf-vmalloc.h>
28 #include "atomisp_cmd.h"
29 #include "atomisp_common.h"
30 #include "atomisp_fops.h"
31 #include "atomisp_internal.h"
32 #include "atomisp_ioctl.h"
33 #include "atomisp-regs.h"
34 #include "atomisp_compat.h"
36 #include "sh_css_hrt.h"
38 #include "gp_device.h"
39 #include "device_access.h"
42 static const char *DRIVER = "atomisp"; /* max size 15 */
43 static const char *CARD = "ATOM ISP"; /* max size 31 */
46 * FIXME: ISP should not know beforehand all CIDs supported by sensor.
47 * Instead, it needs to propagate to sensor unkonwn CIDs.
49 static struct v4l2_queryctrl ci_v4l2_controls[] = {
51 .id = V4L2_CID_AUTO_WHITE_BALANCE,
52 .type = V4L2_CTRL_TYPE_BOOLEAN,
53 .name = "Automatic White Balance",
60 .id = V4L2_CID_RED_BALANCE,
61 .type = V4L2_CTRL_TYPE_INTEGER,
62 .name = "Red Balance",
66 .default_value = 0x00,
69 .id = V4L2_CID_BLUE_BALANCE,
70 .type = V4L2_CTRL_TYPE_INTEGER,
71 .name = "Blue Balance",
75 .default_value = 0x00,
79 .type = V4L2_CTRL_TYPE_INTEGER,
84 .default_value = 0x00,
87 .id = V4L2_CID_POWER_LINE_FREQUENCY,
88 .type = V4L2_CTRL_TYPE_MENU,
89 .name = "Light frequency filter",
96 .id = V4L2_CID_COLORFX,
97 .type = V4L2_CTRL_TYPE_INTEGER,
98 .name = "Image Color Effect",
105 .id = V4L2_CID_COLORFX_CBCR,
106 .type = V4L2_CTRL_TYPE_INTEGER,
107 .name = "Image Color Effect CbCr",
114 .id = V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION,
115 .type = V4L2_CTRL_TYPE_INTEGER,
116 .name = "Bad Pixel Correction",
123 .id = V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC,
124 .type = V4L2_CTRL_TYPE_INTEGER,
132 .id = V4L2_CID_ATOMISP_VIDEO_STABLIZATION,
133 .type = V4L2_CTRL_TYPE_INTEGER,
134 .name = "Video Stablization",
141 .id = V4L2_CID_ATOMISP_FIXED_PATTERN_NR,
142 .type = V4L2_CTRL_TYPE_INTEGER,
143 .name = "Fixed Pattern Noise Reduction",
150 .id = V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION,
151 .type = V4L2_CTRL_TYPE_INTEGER,
152 .name = "False Color Correction",
159 .id = V4L2_CID_REQUEST_FLASH,
160 .type = V4L2_CTRL_TYPE_INTEGER,
161 .name = "Request flash frames",
168 .id = V4L2_CID_ATOMISP_LOW_LIGHT,
169 .type = V4L2_CTRL_TYPE_BOOLEAN,
170 .name = "Low light mode",
177 .id = V4L2_CID_BIN_FACTOR_HORZ,
178 .type = V4L2_CTRL_TYPE_INTEGER,
179 .name = "Horizontal binning factor",
186 .id = V4L2_CID_BIN_FACTOR_VERT,
187 .type = V4L2_CTRL_TYPE_INTEGER,
188 .name = "Vertical binning factor",
195 .id = V4L2_CID_2A_STATUS,
196 .type = V4L2_CTRL_TYPE_BITMASK,
197 .name = "AE and AWB status",
199 .maximum = V4L2_2A_STATUS_AE_READY | V4L2_2A_STATUS_AWB_READY,
204 .id = V4L2_CID_EXPOSURE,
205 .type = V4L2_CTRL_TYPE_INTEGER,
213 .id = V4L2_CID_EXPOSURE_ZONE_NUM,
214 .type = V4L2_CTRL_TYPE_INTEGER,
215 .name = "one-time exposure zone number",
222 .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
223 .type = V4L2_CTRL_TYPE_INTEGER,
224 .name = "Exposure auto priority",
225 .minimum = V4L2_EXPOSURE_AUTO,
226 .maximum = V4L2_EXPOSURE_APERTURE_PRIORITY,
228 .default_value = V4L2_EXPOSURE_AUTO,
231 .id = V4L2_CID_SCENE_MODE,
232 .type = V4L2_CTRL_TYPE_INTEGER,
233 .name = "scene mode",
240 .id = V4L2_CID_ISO_SENSITIVITY,
241 .type = V4L2_CTRL_TYPE_INTEGER,
249 .id = V4L2_CID_ISO_SENSITIVITY_AUTO,
250 .type = V4L2_CTRL_TYPE_INTEGER,
252 .minimum = V4L2_ISO_SENSITIVITY_MANUAL,
253 .maximum = V4L2_ISO_SENSITIVITY_AUTO,
255 .default_value = V4L2_ISO_SENSITIVITY_AUTO,
258 .id = V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
259 .type = V4L2_CTRL_TYPE_INTEGER,
260 .name = "white balance",
267 .id = V4L2_CID_EXPOSURE_METERING,
268 .type = V4L2_CTRL_TYPE_MENU,
276 .id = V4L2_CID_3A_LOCK,
277 .type = V4L2_CTRL_TYPE_BITMASK,
280 .maximum = V4L2_LOCK_EXPOSURE | V4L2_LOCK_WHITE_BALANCE
286 .id = V4L2_CID_TEST_PATTERN,
287 .type = V4L2_CTRL_TYPE_INTEGER,
288 .name = "Test Pattern",
295 .id = V4L2_CID_TEST_PATTERN_COLOR_R,
296 .type = V4L2_CTRL_TYPE_INTEGER,
297 .name = "Test Pattern Solid Color R",
304 .id = V4L2_CID_TEST_PATTERN_COLOR_GR,
305 .type = V4L2_CTRL_TYPE_INTEGER,
306 .name = "Test Pattern Solid Color GR",
313 .id = V4L2_CID_TEST_PATTERN_COLOR_GB,
314 .type = V4L2_CTRL_TYPE_INTEGER,
315 .name = "Test Pattern Solid Color GB",
322 .id = V4L2_CID_TEST_PATTERN_COLOR_B,
323 .type = V4L2_CTRL_TYPE_INTEGER,
324 .name = "Test Pattern Solid Color B",
332 static const u32 ctrls_num = ARRAY_SIZE(ci_v4l2_controls);
335 * supported V4L2 fmts and resolutions
337 const struct atomisp_format_bridge atomisp_output_fmts[] = {
339 .pixelformat = V4L2_PIX_FMT_YUV420,
341 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV420,
342 .sh_fmt = IA_CSS_FRAME_FORMAT_YUV420,
343 .description = "YUV420, planar",
346 .pixelformat = V4L2_PIX_FMT_YVU420,
348 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YVU420,
349 .sh_fmt = IA_CSS_FRAME_FORMAT_YV12,
350 .description = "YVU420, planar",
353 .pixelformat = V4L2_PIX_FMT_YUV422P,
355 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV422P,
356 .sh_fmt = IA_CSS_FRAME_FORMAT_YUV422,
357 .description = "YUV422, planar",
360 .pixelformat = V4L2_PIX_FMT_YUV444,
362 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV444,
363 .sh_fmt = IA_CSS_FRAME_FORMAT_YUV444,
364 .description = "YUV444"
366 .pixelformat = V4L2_PIX_FMT_NV12,
368 .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV12,
369 .sh_fmt = IA_CSS_FRAME_FORMAT_NV12,
370 .description = "NV12, Y-plane, CbCr interleaved",
373 .pixelformat = V4L2_PIX_FMT_NV21,
375 .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV21,
376 .sh_fmt = IA_CSS_FRAME_FORMAT_NV21,
377 .description = "NV21, Y-plane, CbCr interleaved",
380 .pixelformat = V4L2_PIX_FMT_NV16,
382 .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV16,
383 .sh_fmt = IA_CSS_FRAME_FORMAT_NV16,
384 .description = "NV16, Y-plane, CbCr interleaved",
387 .pixelformat = V4L2_PIX_FMT_YUYV,
389 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUYV,
390 .sh_fmt = IA_CSS_FRAME_FORMAT_YUYV,
391 .description = "YUYV, interleaved"
393 .pixelformat = V4L2_PIX_FMT_UYVY,
395 .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
396 .sh_fmt = IA_CSS_FRAME_FORMAT_UYVY,
397 .description = "UYVY, interleaved"
398 }, { /* This one is for parallel sensors! DO NOT USE! */
399 .pixelformat = V4L2_PIX_FMT_UYVY,
401 .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
402 .sh_fmt = IA_CSS_FRAME_FORMAT_UYVY,
403 .description = "UYVY, interleaved"
405 .pixelformat = V4L2_PIX_FMT_SBGGR16,
407 .mbus_code = V4L2_MBUS_FMT_CUSTOM_SBGGR16,
408 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
409 .description = "Bayer 16"
411 .pixelformat = V4L2_PIX_FMT_SBGGR8,
413 .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
414 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
415 .description = "Bayer 8"
417 .pixelformat = V4L2_PIX_FMT_SGBRG8,
419 .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
420 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
421 .description = "Bayer 8"
423 .pixelformat = V4L2_PIX_FMT_SGRBG8,
425 .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
426 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
427 .description = "Bayer 8"
429 .pixelformat = V4L2_PIX_FMT_SRGGB8,
431 .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
432 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
433 .description = "Bayer 8"
435 .pixelformat = V4L2_PIX_FMT_SBGGR10,
437 .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
438 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
439 .description = "Bayer 10"
441 .pixelformat = V4L2_PIX_FMT_SGBRG10,
443 .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
444 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
445 .description = "Bayer 10"
447 .pixelformat = V4L2_PIX_FMT_SGRBG10,
449 .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
450 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
451 .description = "Bayer 10"
453 .pixelformat = V4L2_PIX_FMT_SRGGB10,
455 .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
456 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
457 .description = "Bayer 10"
459 .pixelformat = V4L2_PIX_FMT_SBGGR12,
461 .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
462 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
463 .description = "Bayer 12"
465 .pixelformat = V4L2_PIX_FMT_SGBRG12,
467 .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
468 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
469 .description = "Bayer 12"
471 .pixelformat = V4L2_PIX_FMT_SGRBG12,
473 .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
474 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
475 .description = "Bayer 12"
477 .pixelformat = V4L2_PIX_FMT_SRGGB12,
479 .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
480 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
481 .description = "Bayer 12"
483 .pixelformat = V4L2_PIX_FMT_RGB32,
485 .mbus_code = V4L2_MBUS_FMT_CUSTOM_RGB32,
486 .sh_fmt = IA_CSS_FRAME_FORMAT_RGBA888,
487 .description = "32 RGB 8-8-8-8"
489 .pixelformat = V4L2_PIX_FMT_RGB565,
491 .mbus_code = MEDIA_BUS_FMT_BGR565_2X8_LE,
492 .sh_fmt = IA_CSS_FRAME_FORMAT_RGB565,
493 .description = "16 RGB 5-6-5"
496 .pixelformat = V4L2_PIX_FMT_JPEG,
498 .mbus_code = MEDIA_BUS_FMT_JPEG_1X8,
499 .sh_fmt = IA_CSS_FRAME_FORMAT_BINARY_8,
500 .description = "JPEG"
502 /* This is a custom format being used by M10MO to send the RAW data */
503 .pixelformat = V4L2_PIX_FMT_CUSTOM_M10MO_RAW,
505 .mbus_code = V4L2_MBUS_FMT_CUSTOM_M10MO_RAW,
506 .sh_fmt = IA_CSS_FRAME_FORMAT_BINARY_8,
507 .description = "Custom RAW for M10MO"
512 const struct atomisp_format_bridge *
513 atomisp_get_format_bridge(unsigned int pixelformat)
517 for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
518 if (atomisp_output_fmts[i].pixelformat == pixelformat)
519 return &atomisp_output_fmts[i];
525 const struct atomisp_format_bridge *
526 atomisp_get_format_bridge_from_mbus(u32 mbus_code)
530 for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
531 if (mbus_code == atomisp_output_fmts[i].mbus_code)
532 return &atomisp_output_fmts[i];
538 int atomisp_pipe_check(struct atomisp_video_pipe *pipe, bool settings_change)
540 lockdep_assert_held(&pipe->isp->mutex);
542 if (pipe->isp->isp_fatal_error)
545 switch (pipe->asd->streaming) {
546 case ATOMISP_DEVICE_STREAMING_DISABLED:
548 case ATOMISP_DEVICE_STREAMING_ENABLED:
549 if (settings_change) {
550 dev_err(pipe->isp->dev, "Set fmt/input IOCTL while streaming\n");
554 case ATOMISP_DEVICE_STREAMING_STOPPING:
555 dev_err(pipe->isp->dev, "IOCTL issued while stopping\n");
566 * return ISP capabilities
568 static int atomisp_querycap(struct file *file, void *fh,
569 struct v4l2_capability *cap)
571 struct video_device *vdev = video_devdata(file);
572 struct atomisp_device *isp = video_get_drvdata(vdev);
574 strscpy(cap->driver, DRIVER, sizeof(cap->driver));
575 strscpy(cap->card, CARD, sizeof(cap->card));
576 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", dev_name(isp->dev));
582 * enum input are used to check primary/secondary camera
584 static int atomisp_enum_input(struct file *file, void *fh,
585 struct v4l2_input *input)
587 struct video_device *vdev = video_devdata(file);
588 struct atomisp_device *isp = video_get_drvdata(vdev);
589 int index = input->index;
590 struct v4l2_subdev *motor;
592 if (index >= isp->input_cnt)
595 if (!isp->inputs[index].camera)
598 memset(input, 0, sizeof(struct v4l2_input));
599 strscpy(input->name, isp->inputs[index].camera->name,
600 sizeof(input->name));
603 * HACK: append actuator's name to sensor's
604 * As currently userspace can't talk directly to subdev nodes, this
605 * ioctl is the only way to enum inputs + possible external actuators
606 * for 3A tuning purpose.
609 motor = isp->inputs[index].motor;
613 if (motor && strlen(motor->name) > 0) {
614 const int cur_len = strlen(input->name);
615 const int max_size = sizeof(input->name) - cur_len - 1;
618 input->name[cur_len] = '+';
619 strscpy(&input->name[cur_len + 1],
620 motor->name, max_size);
624 input->type = V4L2_INPUT_TYPE_CAMERA;
625 input->index = index;
626 input->reserved[0] = isp->inputs[index].type;
627 input->reserved[1] = isp->inputs[index].port;
633 atomisp_subdev_streaming_count(struct atomisp_sub_device *asd)
635 return asd->video_out_preview.capq.streaming
636 + asd->video_out_capture.capq.streaming
637 + asd->video_out_video_capture.capq.streaming
638 + asd->video_out_vf.capq.streaming;
641 unsigned int atomisp_streaming_count(struct atomisp_device *isp)
645 for (i = 0, sum = 0; i < isp->num_of_streams; i++)
646 sum += isp->asd[i].streaming ==
647 ATOMISP_DEVICE_STREAMING_ENABLED;
653 * get input are used to get current primary/secondary camera
655 static int atomisp_g_input(struct file *file, void *fh, unsigned int *input)
657 struct video_device *vdev = video_devdata(file);
658 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
660 *input = asd->input_curr;
665 * set input are used to set current primary/secondary camera
667 static int atomisp_s_input(struct file *file, void *fh, unsigned int input)
669 struct video_device *vdev = video_devdata(file);
670 struct atomisp_device *isp = video_get_drvdata(vdev);
671 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
672 struct atomisp_sub_device *asd = pipe->asd;
673 struct v4l2_subdev *camera = NULL;
674 struct v4l2_subdev *motor;
677 ret = atomisp_pipe_check(pipe, true);
681 if (input >= ATOM_ISP_MAX_INPUTS || input >= isp->input_cnt) {
682 dev_dbg(isp->dev, "input_cnt: %d\n", isp->input_cnt);
687 * check whether the request camera:
689 * 2: if in use, whether it is used by other streams
691 if (isp->inputs[input].asd && isp->inputs[input].asd != asd) {
693 "%s, camera is already used by stream: %d\n", __func__,
694 isp->inputs[input].asd->index);
698 camera = isp->inputs[input].camera;
700 dev_err(isp->dev, "%s, no camera\n", __func__);
704 /* power off the current owned sensor, as it is not used this time */
705 if (isp->inputs[asd->input_curr].asd == asd &&
706 asd->input_curr != input) {
707 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
711 "Failed to power-off sensor\n");
712 /* clear the asd field to show this camera is not used */
713 isp->inputs[asd->input_curr].asd = NULL;
716 /* powe on the new sensor */
717 ret = v4l2_subdev_call(isp->inputs[input].camera, core, s_power, 1);
719 dev_err(isp->dev, "Failed to power-on sensor\n");
723 * Some sensor driver resets the run mode during power-on, thus force
724 * update the run mode to sensor after power-on.
726 atomisp_update_run_mode(asd);
728 /* select operating sensor */
729 ret = v4l2_subdev_call(isp->inputs[input].camera, video, s_routing,
730 0, isp->inputs[input].sensor_index, 0);
731 if (ret && (ret != -ENOIOCTLCMD)) {
732 dev_err(isp->dev, "Failed to select sensor\n");
737 motor = isp->inputs[input].motor;
741 ret = v4l2_subdev_call(motor, core, s_power, 1);
745 ret = v4l2_subdev_call(motor, core, init, 1);
747 asd->input_curr = input;
748 /* mark this camera is used by the current stream */
749 isp->inputs[input].asd = asd;
754 static int atomisp_enum_framesizes(struct file *file, void *priv,
755 struct v4l2_frmsizeenum *fsize)
757 struct video_device *vdev = video_devdata(file);
758 struct atomisp_device *isp = video_get_drvdata(vdev);
759 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
760 struct v4l2_subdev_frame_size_enum fse = {
761 .index = fsize->index,
762 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
766 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
767 pad, enum_frame_size, NULL, &fse);
771 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
772 fsize->discrete.width = fse.max_width - pad_w;
773 fsize->discrete.height = fse.max_height - pad_h;
778 static int atomisp_enum_frameintervals(struct file *file, void *priv,
779 struct v4l2_frmivalenum *fival)
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_frame_interval_enum fie = {
785 .code = atomisp_in_fmt_conv[0].code,
786 .index = fival->index,
787 .width = fival->width,
788 .height = fival->height,
789 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
793 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
794 pad, enum_frame_interval, NULL,
799 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
800 fival->discrete = fie.interval;
805 static int atomisp_enum_fmt_cap(struct file *file, void *fh,
806 struct v4l2_fmtdesc *f)
808 struct video_device *vdev = video_devdata(file);
809 struct atomisp_device *isp = video_get_drvdata(vdev);
810 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
811 struct v4l2_subdev_mbus_code_enum code = {
812 .which = V4L2_SUBDEV_FORMAT_ACTIVE,
814 const struct atomisp_format_bridge *format;
815 struct v4l2_subdev *camera;
816 unsigned int i, fi = 0;
819 camera = isp->inputs[asd->input_curr].camera;
821 dev_err(isp->dev, "%s(): camera is NULL, device is %s\n",
822 __func__, vdev->name);
826 rval = v4l2_subdev_call(camera, pad, enum_mbus_code, NULL, &code);
827 if (rval == -ENOIOCTLCMD) {
829 "enum_mbus_code pad op not supported by %s. Please fix your sensor driver!\n",
836 for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
837 format = &atomisp_output_fmts[i];
840 * Is the atomisp-supported format is valid for the
841 * sensor (configuration)? If not, skip it.
843 * FIXME: fix the pipeline to allow sensor format too.
845 if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW)
848 /* Found a match. Now let's pick f->index'th one. */
854 strscpy(f->description, format->description,
855 sizeof(f->description));
856 f->pixelformat = format->pixelformat;
863 static int atomisp_adjust_fmt(struct v4l2_format *f)
865 const struct atomisp_format_bridge *format_bridge;
868 format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
870 padded_width = f->fmt.pix.width + pad_w;
872 if (format_bridge->planar) {
873 f->fmt.pix.bytesperline = padded_width;
874 f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height *
875 DIV_ROUND_UP(format_bridge->depth *
878 f->fmt.pix.bytesperline = DIV_ROUND_UP(format_bridge->depth *
880 f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * f->fmt.pix.bytesperline);
883 if (f->fmt.pix.field == V4L2_FIELD_ANY)
884 f->fmt.pix.field = V4L2_FIELD_NONE;
886 format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
890 /* Currently, raw formats are broken!!! */
891 if (format_bridge->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) {
892 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
894 format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat);
899 padded_width = f->fmt.pix.width + pad_w;
901 if (format_bridge->planar) {
902 f->fmt.pix.bytesperline = padded_width;
903 f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height *
904 DIV_ROUND_UP(format_bridge->depth *
907 f->fmt.pix.bytesperline = DIV_ROUND_UP(format_bridge->depth *
909 f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * f->fmt.pix.bytesperline);
912 if (f->fmt.pix.field == V4L2_FIELD_ANY)
913 f->fmt.pix.field = V4L2_FIELD_NONE;
916 * FIXME: do we need to setup this differently, depending on the
917 * sensor or the pipeline?
919 f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
920 f->fmt.pix.ycbcr_enc = V4L2_YCBCR_ENC_709;
921 f->fmt.pix.xfer_func = V4L2_XFER_FUNC_709;
923 f->fmt.pix.width -= pad_w;
924 f->fmt.pix.height -= pad_h;
929 /* This function looks up the closest available resolution. */
930 static int atomisp_try_fmt_cap(struct file *file, void *fh,
931 struct v4l2_format *f)
933 struct video_device *vdev = video_devdata(file);
937 * atomisp_try_fmt() gived results with padding included, note
938 * (this gets removed again by the atomisp_adjust_fmt() call below.
940 f->fmt.pix.width += pad_w;
941 f->fmt.pix.height += pad_h;
943 ret = atomisp_try_fmt(vdev, &f->fmt.pix, NULL);
947 return atomisp_adjust_fmt(f);
950 static int atomisp_g_fmt_cap(struct file *file, void *fh,
951 struct v4l2_format *f)
953 struct video_device *vdev = video_devdata(file);
954 struct atomisp_video_pipe *pipe;
956 pipe = atomisp_to_video_pipe(vdev);
958 f->fmt.pix = pipe->pix;
960 /* If s_fmt was issued, just return whatever is was previouly set */
961 if (f->fmt.pix.sizeimage)
964 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
965 f->fmt.pix.width = 10000;
966 f->fmt.pix.height = 10000;
968 return atomisp_try_fmt_cap(file, fh, f);
972 * Free videobuffer buffer priv data
974 void atomisp_videobuf_free_buf(struct videobuf_buffer *vb)
976 struct videobuf_vmalloc_memory *vm_mem;
982 if (vm_mem && vm_mem->vaddr) {
983 ia_css_frame_free(vm_mem->vaddr);
984 vm_mem->vaddr = NULL;
989 * this function is used to free video buffer queue
991 static void atomisp_videobuf_free_queue(struct videobuf_queue *q)
995 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
996 atomisp_videobuf_free_buf(q->bufs[i]);
1002 int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd,
1005 struct atomisp_device *isp = asd->isp;
1006 struct atomisp_s3a_buf *s3a_buf = NULL, *_s3a_buf;
1007 struct atomisp_dis_buf *dis_buf = NULL, *_dis_buf;
1008 struct atomisp_metadata_buf *md_buf = NULL, *_md_buf;
1010 struct ia_css_dvs_grid_info *dvs_grid_info =
1011 atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
1014 if (list_empty(&asd->s3a_stats) &&
1015 asd->params.curr_grid_info.s3a_grid.enable) {
1016 count = ATOMISP_CSS_Q_DEPTH +
1017 ATOMISP_S3A_BUF_QUEUE_DEPTH_FOR_HAL;
1018 dev_dbg(isp->dev, "allocating %d 3a buffers\n", count);
1020 s3a_buf = kzalloc(sizeof(struct atomisp_s3a_buf), GFP_KERNEL);
1024 if (atomisp_css_allocate_stat_buffers(
1025 asd, stream_id, s3a_buf, NULL, NULL)) {
1030 list_add_tail(&s3a_buf->list, &asd->s3a_stats);
1034 if (list_empty(&asd->dis_stats) && dvs_grid_info &&
1035 dvs_grid_info->enable) {
1036 count = ATOMISP_CSS_Q_DEPTH + 1;
1037 dev_dbg(isp->dev, "allocating %d dis buffers\n", count);
1039 dis_buf = kzalloc(sizeof(struct atomisp_dis_buf), GFP_KERNEL);
1042 if (atomisp_css_allocate_stat_buffers(
1043 asd, stream_id, NULL, dis_buf, NULL)) {
1048 list_add_tail(&dis_buf->list, &asd->dis_stats);
1052 for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
1053 if (list_empty(&asd->metadata[i]) &&
1054 list_empty(&asd->metadata_ready[i]) &&
1055 list_empty(&asd->metadata_in_css[i])) {
1056 count = ATOMISP_CSS_Q_DEPTH +
1057 ATOMISP_METADATA_QUEUE_DEPTH_FOR_HAL;
1058 dev_dbg(isp->dev, "allocating %d metadata buffers for type %d\n",
1061 md_buf = kzalloc(sizeof(struct atomisp_metadata_buf),
1066 if (atomisp_css_allocate_stat_buffers(
1067 asd, stream_id, NULL, NULL, md_buf)) {
1071 list_add_tail(&md_buf->list, &asd->metadata[i]);
1078 dev_err(isp->dev, "failed to allocate statistics buffers\n");
1080 list_for_each_entry_safe(dis_buf, _dis_buf, &asd->dis_stats, list) {
1081 atomisp_css_free_dis_buffer(dis_buf);
1082 list_del(&dis_buf->list);
1086 list_for_each_entry_safe(s3a_buf, _s3a_buf, &asd->s3a_stats, list) {
1087 atomisp_css_free_3a_buffer(s3a_buf);
1088 list_del(&s3a_buf->list);
1092 for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
1093 list_for_each_entry_safe(md_buf, _md_buf, &asd->metadata[i],
1095 atomisp_css_free_metadata_buffer(md_buf);
1096 list_del(&md_buf->list);
1104 * Initiate Memory Mapping or User Pointer I/O
1106 int atomisp_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *req)
1108 struct video_device *vdev = video_devdata(file);
1109 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1110 struct atomisp_sub_device *asd = pipe->asd;
1111 struct ia_css_frame_info frame_info;
1112 struct ia_css_frame *frame;
1113 struct videobuf_vmalloc_memory *vm_mem;
1114 u16 source_pad = atomisp_subdev_source_pad(vdev);
1117 if (req->count == 0) {
1118 mutex_lock(&pipe->capq.vb_lock);
1119 if (!list_empty(&pipe->capq.stream))
1120 videobuf_queue_cancel(&pipe->capq);
1122 atomisp_videobuf_free_queue(&pipe->capq);
1123 mutex_unlock(&pipe->capq.vb_lock);
1124 /* clear request config id */
1125 memset(pipe->frame_request_config_id, 0,
1126 VIDEO_MAX_FRAME * sizeof(unsigned int));
1127 memset(pipe->frame_params, 0,
1129 sizeof(struct atomisp_css_params_with_list *));
1133 ret = videobuf_reqbufs(&pipe->capq, req);
1137 atomisp_alloc_css_stat_bufs(asd, ATOMISP_INPUT_STREAM_GENERAL);
1140 * for user pointer type, buffers are not really allocated here,
1141 * buffers are setup in QBUF operation through v4l2_buffer structure
1143 if (req->memory == V4L2_MEMORY_USERPTR)
1146 ret = atomisp_get_css_frame_info(asd, source_pad, &frame_info);
1151 * Allocate the real frame here for selected node using our
1152 * memory management function
1154 for (i = 0; i < req->count; i++) {
1155 if (ia_css_frame_allocate_from_info(&frame, &frame_info))
1157 vm_mem = pipe->capq.bufs[i]->priv;
1158 vm_mem->vaddr = frame;
1165 vm_mem = pipe->capq.bufs[i]->priv;
1166 ia_css_frame_free(vm_mem->vaddr);
1170 ia_css_frame_free(asd->vf_frame);
1175 /* application query the status of a buffer */
1176 static int atomisp_querybuf(struct file *file, void *fh,
1177 struct v4l2_buffer *buf)
1179 struct video_device *vdev = video_devdata(file);
1180 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1182 return videobuf_querybuf(&pipe->capq, buf);
1186 * Applications call the VIDIOC_QBUF ioctl to enqueue an empty (capturing) or
1187 * filled (output) buffer in the drivers incoming queue.
1189 static int atomisp_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1191 static const int NOFLUSH_FLAGS = V4L2_BUF_FLAG_NO_CACHE_INVALIDATE |
1192 V4L2_BUF_FLAG_NO_CACHE_CLEAN;
1193 struct video_device *vdev = video_devdata(file);
1194 struct atomisp_device *isp = video_get_drvdata(vdev);
1195 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1196 struct atomisp_sub_device *asd = pipe->asd;
1197 struct videobuf_buffer *vb;
1198 struct videobuf_vmalloc_memory *vm_mem;
1199 struct ia_css_frame_info frame_info;
1200 struct ia_css_frame *handle = NULL;
1205 ret = atomisp_pipe_check(pipe, false);
1209 if (!buf || buf->index >= VIDEO_MAX_FRAME ||
1210 !pipe->capq.bufs[buf->index]) {
1211 dev_err(isp->dev, "Invalid index for qbuf.\n");
1216 * For userptr type frame, we convert user space address to physic
1217 * address and reprograme out page table properly
1219 if (buf->memory == V4L2_MEMORY_USERPTR) {
1220 if (offset_in_page(buf->m.userptr)) {
1221 dev_err(isp->dev, "Error userptr is not page aligned.\n");
1225 vb = pipe->capq.bufs[buf->index];
1231 pgnr = (length + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
1233 if (vb->baddr == buf->m.userptr && vm_mem->vaddr)
1236 if (atomisp_get_css_frame_info(asd,
1237 atomisp_subdev_source_pad(vdev), &frame_info))
1240 ret = ia_css_frame_map(&handle, &frame_info,
1241 (void __user *)buf->m.userptr,
1244 dev_err(isp->dev, "Failed to map user buffer\n");
1248 if (vm_mem->vaddr) {
1249 mutex_lock(&pipe->capq.vb_lock);
1250 ia_css_frame_free(vm_mem->vaddr);
1251 vm_mem->vaddr = NULL;
1252 vb->state = VIDEOBUF_NEEDS_INIT;
1253 mutex_unlock(&pipe->capq.vb_lock);
1256 vm_mem->vaddr = handle;
1258 buf->flags &= ~V4L2_BUF_FLAG_MAPPED;
1259 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1260 buf->flags &= ~V4L2_BUF_FLAG_DONE;
1261 } else if (buf->memory == V4L2_MEMORY_MMAP) {
1262 buf->flags |= V4L2_BUF_FLAG_MAPPED;
1263 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1264 buf->flags &= ~V4L2_BUF_FLAG_DONE;
1267 * For mmap, frames were allocated at request buffers
1272 if (!((buf->flags & NOFLUSH_FLAGS) == NOFLUSH_FLAGS))
1275 if (!atomisp_is_vf_pipe(pipe) &&
1276 (buf->reserved2 & ATOMISP_BUFFER_HAS_PER_FRAME_SETTING)) {
1277 /* this buffer will have a per-frame parameter */
1278 pipe->frame_request_config_id[buf->index] = buf->reserved2 &
1279 ~ATOMISP_BUFFER_HAS_PER_FRAME_SETTING;
1281 "This buffer requires per_frame setting which has isp_config_id %d\n",
1282 pipe->frame_request_config_id[buf->index]);
1284 pipe->frame_request_config_id[buf->index] = 0;
1287 pipe->frame_params[buf->index] = NULL;
1289 mutex_unlock(&isp->mutex);
1290 ret = videobuf_qbuf(&pipe->capq, buf);
1291 mutex_lock(&isp->mutex);
1295 /* TODO: do this better, not best way to queue to css */
1296 if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) {
1297 if (!list_empty(&pipe->buffers_waiting_for_param)) {
1298 atomisp_handle_parameter_and_buffer(pipe);
1300 atomisp_qbuffers_to_css(asd);
1305 * Workaround: Due to the design of HALv3,
1306 * sometimes in ZSL or SDV mode HAL needs to
1307 * capture multiple images within one streaming cycle.
1308 * But the capture number cannot be determined by HAL.
1309 * So HAL only sets the capture number to be 1 and queue multiple
1310 * buffers. Atomisp driver needs to check this case and re-trigger
1311 * CSS to do capture when new buffer is queued.
1313 if (asd->continuous_mode->val &&
1314 atomisp_subdev_source_pad(vdev)
1315 == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE &&
1316 pipe->capq.streaming &&
1317 !asd->enable_raw_buffer_lock->val &&
1318 asd->params.offline_parm.num_captures == 1) {
1319 asd->pending_capture_request++;
1320 dev_dbg(isp->dev, "Add one pending capture request.\n");
1323 dev_dbg(isp->dev, "qbuf buffer %d (%s) for asd%d\n", buf->index,
1324 vdev->name, asd->index);
1329 static int __get_frame_exp_id(struct atomisp_video_pipe *pipe,
1330 struct v4l2_buffer *buf)
1332 struct videobuf_vmalloc_memory *vm_mem;
1333 struct ia_css_frame *handle;
1336 for (i = 0; pipe->capq.bufs[i]; i++) {
1337 vm_mem = pipe->capq.bufs[i]->priv;
1338 handle = vm_mem->vaddr;
1339 if (buf->index == pipe->capq.bufs[i]->i && handle)
1340 return handle->exp_id;
1346 * Applications call the VIDIOC_DQBUF ioctl to dequeue a filled (capturing) or
1347 * displayed (output buffer)from the driver's outgoing queue
1349 static int atomisp_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1351 struct video_device *vdev = video_devdata(file);
1352 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1353 struct atomisp_sub_device *asd = pipe->asd;
1354 struct atomisp_device *isp = video_get_drvdata(vdev);
1357 ret = atomisp_pipe_check(pipe, false);
1361 mutex_unlock(&isp->mutex);
1362 ret = videobuf_dqbuf(&pipe->capq, buf, file->f_flags & O_NONBLOCK);
1363 mutex_lock(&isp->mutex);
1366 dev_dbg(isp->dev, "<%s: %d\n", __func__, ret);
1370 buf->bytesused = pipe->pix.sizeimage;
1371 buf->reserved = asd->frame_status[buf->index];
1375 * Currently frame_status in the enum type which takes no more lower
1377 * use bit[31:16] for exp_id as it is only in the range of 1~255
1379 buf->reserved &= 0x0000ffff;
1380 if (!(buf->flags & V4L2_BUF_FLAG_ERROR))
1381 buf->reserved |= __get_frame_exp_id(pipe, buf) << 16;
1382 buf->reserved2 = pipe->frame_config_id[buf->index];
1385 "dqbuf buffer %d (%s) for asd%d with exp_id %d, isp_config_id %d\n",
1386 buf->index, vdev->name, asd->index, buf->reserved >> 16,
1391 enum ia_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device *asd)
1393 if (ATOMISP_USE_YUVPP(asd))
1394 return IA_CSS_PIPE_ID_YUVPP;
1396 if (asd->continuous_mode->val) {
1397 if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)
1398 return IA_CSS_PIPE_ID_VIDEO;
1400 return IA_CSS_PIPE_ID_PREVIEW;
1404 * Disable vf_pp and run CSS in video mode. This allows using ISP
1405 * scaling but it has one frame delay due to CSS internal buffering.
1407 if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER)
1408 return IA_CSS_PIPE_ID_VIDEO;
1411 * Disable vf_pp and run CSS in still capture mode. In this mode
1412 * CSS does not cause extra latency with buffering, but scaling
1415 if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT)
1416 return IA_CSS_PIPE_ID_CAPTURE;
1418 switch (asd->run_mode->val) {
1419 case ATOMISP_RUN_MODE_PREVIEW:
1420 return IA_CSS_PIPE_ID_PREVIEW;
1421 case ATOMISP_RUN_MODE_VIDEO:
1422 return IA_CSS_PIPE_ID_VIDEO;
1423 case ATOMISP_RUN_MODE_STILL_CAPTURE:
1425 return IA_CSS_PIPE_ID_CAPTURE;
1429 static unsigned int atomisp_sensor_start_stream(struct atomisp_sub_device *asd)
1431 if (asd->vfpp->val != ATOMISP_VFPP_ENABLE ||
1435 if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO ||
1436 (asd->run_mode->val == ATOMISP_RUN_MODE_STILL_CAPTURE &&
1437 !atomisp_is_mbuscode_raw(
1439 asd->capture_pad].fmt.code) &&
1440 !asd->continuous_mode->val))
1446 int atomisp_stream_on_master_slave_sensor(struct atomisp_device *isp,
1449 unsigned int master, slave, delay_slave = 0;
1452 master = ATOMISP_DEPTH_DEFAULT_MASTER_SENSOR;
1453 slave = ATOMISP_DEPTH_DEFAULT_SLAVE_SENSOR;
1455 "depth mode use default master=%s.slave=%s.\n",
1456 isp->inputs[master].camera->name,
1457 isp->inputs[slave].camera->name);
1459 ret = v4l2_subdev_call(isp->inputs[master].camera, core,
1460 ioctl, ATOMISP_IOC_G_DEPTH_SYNC_COMP,
1464 "get depth sensor %s compensation delay failed.\n",
1465 isp->inputs[master].camera->name);
1467 ret = v4l2_subdev_call(isp->inputs[master].camera,
1468 video, s_stream, 1);
1470 dev_err(isp->dev, "depth mode master sensor %s stream-on failed.\n",
1471 isp->inputs[master].camera->name);
1475 if (delay_slave != 0)
1476 udelay(delay_slave);
1478 ret = v4l2_subdev_call(isp->inputs[slave].camera,
1479 video, s_stream, 1);
1481 dev_err(isp->dev, "depth mode slave sensor %s stream-on failed.\n",
1482 isp->inputs[slave].camera->name);
1483 v4l2_subdev_call(isp->inputs[master].camera, video, s_stream, 0);
1491 /* Input system HW workaround */
1492 /* Input system address translation corrupts burst during */
1493 /* invalidate. SW workaround for this is to set burst length */
1494 /* manually to 128 in case of 13MPx snapshot and to 1 otherwise. */
1495 static void atomisp_dma_burst_len_cfg(struct atomisp_sub_device *asd)
1497 struct v4l2_mbus_framefmt *sink;
1499 sink = atomisp_subdev_get_ffmt(&asd->subdev, NULL,
1500 V4L2_SUBDEV_FORMAT_ACTIVE,
1501 ATOMISP_SUBDEV_PAD_SINK);
1503 if (sink->width * sink->height >= 4096 * 3072)
1504 atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x7F);
1506 atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x00);
1510 * This ioctl start the capture during streaming I/O.
1512 static int atomisp_streamon(struct file *file, void *fh,
1513 enum v4l2_buf_type type)
1515 struct video_device *vdev = video_devdata(file);
1516 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1517 struct atomisp_sub_device *asd = pipe->asd;
1518 struct atomisp_device *isp = video_get_drvdata(vdev);
1519 struct pci_dev *pdev = to_pci_dev(isp->dev);
1520 enum ia_css_pipe_id css_pipe_id;
1521 unsigned int sensor_start_stream;
1522 unsigned long irqflags;
1525 dev_dbg(isp->dev, "Start stream on pad %d for asd%d\n",
1526 atomisp_subdev_source_pad(vdev), asd->index);
1528 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1529 dev_dbg(isp->dev, "unsupported v4l2 buf type\n");
1533 ret = atomisp_pipe_check(pipe, false);
1537 if (pipe->capq.streaming)
1540 /* Input system HW workaround */
1541 atomisp_dma_burst_len_cfg(asd);
1544 * The number of streaming video nodes is based on which
1545 * binary is going to be run.
1547 sensor_start_stream = atomisp_sensor_start_stream(asd);
1549 spin_lock_irqsave(&pipe->irq_lock, irqflags);
1550 if (list_empty(&pipe->capq.stream)) {
1551 spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
1552 dev_dbg(isp->dev, "no buffer in the queue\n");
1555 spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
1557 ret = videobuf_streamon(&pipe->capq);
1561 /* Reset pending capture request count. */
1562 asd->pending_capture_request = 0;
1564 if (atomisp_subdev_streaming_count(asd) > sensor_start_stream) {
1565 /* trigger still capture */
1566 if (asd->continuous_mode->val &&
1567 atomisp_subdev_source_pad(vdev)
1568 == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) {
1569 if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)
1570 dev_dbg(isp->dev, "SDV last video raw buffer id: %u\n",
1571 asd->latest_preview_exp_id);
1573 dev_dbg(isp->dev, "ZSL last preview raw buffer id: %u\n",
1574 asd->latest_preview_exp_id);
1576 if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) {
1577 flush_work(&asd->delayed_init_work);
1578 mutex_unlock(&isp->mutex);
1579 ret = wait_for_completion_interruptible(&asd->init_done);
1580 mutex_lock(&isp->mutex);
1582 return -ERESTARTSYS;
1585 /* handle per_frame_setting parameter and buffers */
1586 atomisp_handle_parameter_and_buffer(pipe);
1589 * only ZSL/SDV capture request will be here, raise
1590 * the ISP freq to the highest possible to minimize
1593 atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_MAX, false);
1595 * When asd->enable_raw_buffer_lock->val is true,
1596 * An extra IOCTL is needed to call
1597 * atomisp_css_exp_id_capture and trigger real capture
1599 if (!asd->enable_raw_buffer_lock->val) {
1600 ret = atomisp_css_offline_capture_configure(asd,
1601 asd->params.offline_parm.num_captures,
1602 asd->params.offline_parm.skip_frames,
1603 asd->params.offline_parm.offset);
1608 atomisp_qbuffers_to_css(asd);
1612 if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) {
1613 atomisp_qbuffers_to_css(asd);
1617 css_pipe_id = atomisp_get_css_pipe_id(asd);
1619 /* Invalidate caches. FIXME: should flush only necessary buffers */
1622 if (asd->params.css_update_params_needed) {
1623 atomisp_apply_css_parameters(asd, &asd->params.css_param);
1624 if (asd->params.css_param.update_flag.dz_config)
1625 asd->params.config.dz_config = &asd->params.css_param.dz_config;
1626 atomisp_css_update_isp_params(asd);
1627 asd->params.css_update_params_needed = false;
1628 memset(&asd->params.css_param.update_flag, 0,
1629 sizeof(struct atomisp_parameters));
1631 asd->params.dvs_6axis = NULL;
1633 ret = atomisp_css_start(asd, css_pipe_id, false);
1637 spin_lock_irqsave(&isp->lock, irqflags);
1638 asd->streaming = ATOMISP_DEVICE_STREAMING_ENABLED;
1639 spin_unlock_irqrestore(&isp->lock, irqflags);
1640 atomic_set(&asd->sof_count, -1);
1641 atomic_set(&asd->sequence, -1);
1642 atomic_set(&asd->sequence_temp, -1);
1644 asd->params.dis_proj_data_valid = false;
1645 asd->latest_preview_exp_id = 0;
1646 asd->postview_exp_id = 1;
1647 asd->preview_exp_id = 1;
1649 /* handle per_frame_setting parameter and buffers */
1650 atomisp_handle_parameter_and_buffer(pipe);
1652 atomisp_qbuffers_to_css(asd);
1654 /* Only start sensor when the last streaming instance started */
1655 if (atomisp_subdev_streaming_count(asd) < sensor_start_stream)
1660 asd->params.num_flash_frames = 0;
1661 asd->params.flash_state = ATOMISP_FLASH_IDLE;
1662 atomisp_setup_flash(asd);
1665 atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF,
1666 atomisp_css_valid_sof(isp));
1667 atomisp_csi2_configure(asd);
1669 * set freq to max when streaming count > 1 which indicate
1670 * dual camera would run
1672 if (atomisp_streaming_count(isp) > 1) {
1673 if (atomisp_freq_scaling(isp,
1674 ATOMISP_DFS_MODE_MAX, false) < 0)
1675 dev_dbg(isp->dev, "DFS max mode failed!\n");
1677 if (atomisp_freq_scaling(isp,
1678 ATOMISP_DFS_MODE_AUTO, false) < 0)
1679 dev_dbg(isp->dev, "DFS auto mode failed!\n");
1682 if (asd->depth_mode->val && atomisp_streaming_count(isp) ==
1683 ATOMISP_DEPTH_SENSOR_STREAMON_COUNT) {
1684 ret = atomisp_stream_on_master_slave_sensor(isp, false);
1686 dev_err(isp->dev, "master slave sensor stream on failed!\n");
1689 goto start_delay_wq;
1690 } else if (asd->depth_mode->val && (atomisp_streaming_count(isp) <
1691 ATOMISP_DEPTH_SENSOR_STREAMON_COUNT)) {
1692 goto start_delay_wq;
1695 /* Enable the CSI interface on ANN B0/K0 */
1696 if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
1697 ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) {
1698 pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL,
1699 isp->saved_regs.csi_control | MRFLD_PCI_CSI_CONTROL_CSI_READY);
1702 /* stream on the sensor */
1703 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
1704 video, s_stream, 1);
1706 spin_lock_irqsave(&isp->lock, irqflags);
1707 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
1708 spin_unlock_irqrestore(&isp->lock, irqflags);
1713 if (asd->continuous_mode->val) {
1714 atomisp_subdev_get_ffmt(&asd->subdev, NULL,
1715 V4L2_SUBDEV_FORMAT_ACTIVE,
1716 ATOMISP_SUBDEV_PAD_SINK);
1718 reinit_completion(&asd->init_done);
1719 asd->delayed_init = ATOMISP_DELAYED_INIT_QUEUED;
1720 queue_work(asd->delayed_init_workq, &asd->delayed_init_work);
1722 asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
1728 int atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1730 struct video_device *vdev = video_devdata(file);
1731 struct atomisp_device *isp = video_get_drvdata(vdev);
1732 struct pci_dev *pdev = to_pci_dev(isp->dev);
1733 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1734 struct atomisp_sub_device *asd = pipe->asd;
1735 struct atomisp_video_pipe *capture_pipe = NULL;
1736 struct atomisp_video_pipe *vf_pipe = NULL;
1737 struct atomisp_video_pipe *preview_pipe = NULL;
1738 struct atomisp_video_pipe *video_pipe = NULL;
1739 struct videobuf_buffer *vb, *_vb;
1740 enum ia_css_pipe_id css_pipe_id;
1742 unsigned long flags;
1743 bool first_streamoff = false;
1745 dev_dbg(isp->dev, "Stop stream on pad %d for asd%d\n",
1746 atomisp_subdev_source_pad(vdev), asd->index);
1748 lockdep_assert_held(&isp->mutex);
1750 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1751 dev_dbg(isp->dev, "unsupported v4l2 buf type\n");
1756 * There is no guarantee that the buffers queued to / owned by the ISP
1757 * will properly be returned to the queue when stopping. Set a flag to
1758 * avoid new buffers getting queued and then wait for all the current
1759 * buffers to finish.
1761 pipe->stopping = true;
1762 mutex_unlock(&isp->mutex);
1763 /* wait max 1 second */
1764 ret = wait_event_interruptible_timeout(pipe->capq.wait,
1765 pipe->buffers_in_css == 0, HZ);
1766 mutex_lock(&isp->mutex);
1767 pipe->stopping = false;
1769 return ret ?: -ETIMEDOUT;
1772 * do only videobuf_streamoff for capture & vf pipes in
1773 * case of continuous capture
1775 if (asd->continuous_mode->val &&
1776 atomisp_subdev_source_pad(vdev) != ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
1777 atomisp_subdev_source_pad(vdev) != ATOMISP_SUBDEV_PAD_SOURCE_VIDEO) {
1778 if (atomisp_subdev_source_pad(vdev) == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) {
1779 /* stop continuous still capture if needed */
1780 if (asd->params.offline_parm.num_captures == -1)
1781 atomisp_css_offline_capture_configure(asd,
1783 atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_AUTO, false);
1786 return videobuf_streamoff(&pipe->capq);
1789 if (!pipe->capq.streaming)
1792 if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED)
1793 first_streamoff = true;
1795 spin_lock_irqsave(&isp->lock, flags);
1796 if (atomisp_subdev_streaming_count(asd) == 1)
1797 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
1799 asd->streaming = ATOMISP_DEVICE_STREAMING_STOPPING;
1800 spin_unlock_irqrestore(&isp->lock, flags);
1802 if (!first_streamoff) {
1803 ret = videobuf_streamoff(&pipe->capq);
1809 atomisp_clear_css_buffer_counters(asd);
1810 atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false);
1812 if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) {
1813 cancel_work_sync(&asd->delayed_init_work);
1814 asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
1817 css_pipe_id = atomisp_get_css_pipe_id(asd);
1818 atomisp_css_stop(asd, css_pipe_id, false);
1820 /* cancel work queue*/
1821 if (asd->video_out_capture.users) {
1822 capture_pipe = &asd->video_out_capture;
1823 wake_up_interruptible(&capture_pipe->capq.wait);
1825 if (asd->video_out_vf.users) {
1826 vf_pipe = &asd->video_out_vf;
1827 wake_up_interruptible(&vf_pipe->capq.wait);
1829 if (asd->video_out_preview.users) {
1830 preview_pipe = &asd->video_out_preview;
1831 wake_up_interruptible(&preview_pipe->capq.wait);
1833 if (asd->video_out_video_capture.users) {
1834 video_pipe = &asd->video_out_video_capture;
1835 wake_up_interruptible(&video_pipe->capq.wait);
1837 ret = videobuf_streamoff(&pipe->capq);
1841 /* cleanup css here */
1842 /* no need for this, as ISP will be reset anyway */
1843 /*atomisp_flush_bufs_in_css(isp);*/
1845 spin_lock_irqsave(&pipe->irq_lock, flags);
1846 list_for_each_entry_safe(vb, _vb, &pipe->activeq, queue) {
1847 vb->state = VIDEOBUF_PREPARED;
1848 list_del(&vb->queue);
1850 list_for_each_entry_safe(vb, _vb, &pipe->buffers_waiting_for_param, queue) {
1851 vb->state = VIDEOBUF_PREPARED;
1852 list_del(&vb->queue);
1853 pipe->frame_request_config_id[vb->i] = 0;
1855 spin_unlock_irqrestore(&pipe->irq_lock, flags);
1857 atomisp_subdev_cleanup_pending_events(asd);
1859 if (atomisp_subdev_streaming_count(asd) + 1
1860 != atomisp_sensor_start_stream(asd))
1863 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
1864 video, s_stream, 0);
1867 asd->params.num_flash_frames = 0;
1868 asd->params.flash_state = ATOMISP_FLASH_IDLE;
1871 /* if other streams are running, isp should not be powered off */
1872 if (atomisp_streaming_count(isp)) {
1873 atomisp_css_flush(isp);
1877 /* Disable the CSI interface on ANN B0/K0 */
1878 if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
1879 ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) {
1880 pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL,
1881 isp->saved_regs.csi_control & ~MRFLD_PCI_CSI_CONTROL_CSI_READY);
1884 if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false))
1885 dev_warn(isp->dev, "DFS failed.\n");
1887 * ISP work around, need to reset isp
1888 * Is it correct time to reset ISP when first node does streamoff?
1890 if (isp->sw_contex.power_state == ATOM_ISP_POWER_UP) {
1892 bool recreate_streams[MAX_STREAM_NUM] = {0};
1894 if (isp->isp_timeout)
1895 dev_err(isp->dev, "%s: Resetting with WA activated",
1898 * It is possible that the other asd stream is in the stage
1899 * that v4l2_setfmt is just get called on it, which will
1900 * create css stream on that stream. But at this point, there
1901 * is no way to destroy the css stream created on that stream.
1903 * So force stream destroy here.
1905 for (i = 0; i < isp->num_of_streams; i++) {
1906 if (isp->asd[i].stream_prepared) {
1907 atomisp_destroy_pipes_stream_force(&isp->
1909 recreate_streams[i] = true;
1913 /* disable PUNIT/ISP acknowlede/handshake - SRSE=3 */
1914 pci_write_config_dword(pdev, PCI_I_CONTROL,
1915 isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK);
1916 dev_err(isp->dev, "atomisp_reset");
1918 for (i = 0; i < isp->num_of_streams; i++) {
1919 if (recreate_streams[i]) {
1922 ret2 = atomisp_create_pipes_stream(&isp->asd[i]);
1924 dev_err(isp->dev, "%s error re-creating streams: %d\n",
1931 isp->isp_timeout = false;
1937 * To get the current value of a control.
1938 * applications initialize the id field of a struct v4l2_control and
1939 * call this ioctl with a pointer to this structure
1941 static int atomisp_g_ctrl(struct file *file, void *fh,
1942 struct v4l2_control *control)
1944 struct video_device *vdev = video_devdata(file);
1945 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
1946 struct atomisp_device *isp = video_get_drvdata(vdev);
1947 int i, ret = -EINVAL;
1949 for (i = 0; i < ctrls_num; i++) {
1950 if (ci_v4l2_controls[i].id == control->id) {
1959 switch (control->id) {
1960 case V4L2_CID_IRIS_ABSOLUTE:
1961 case V4L2_CID_EXPOSURE_ABSOLUTE:
1962 case V4L2_CID_FNUMBER_ABSOLUTE:
1963 case V4L2_CID_2A_STATUS:
1964 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
1965 case V4L2_CID_EXPOSURE:
1966 case V4L2_CID_EXPOSURE_AUTO:
1967 case V4L2_CID_SCENE_MODE:
1968 case V4L2_CID_ISO_SENSITIVITY:
1969 case V4L2_CID_ISO_SENSITIVITY_AUTO:
1970 case V4L2_CID_CONTRAST:
1971 case V4L2_CID_SATURATION:
1972 case V4L2_CID_SHARPNESS:
1973 case V4L2_CID_3A_LOCK:
1974 case V4L2_CID_EXPOSURE_ZONE_NUM:
1975 case V4L2_CID_TEST_PATTERN:
1976 case V4L2_CID_TEST_PATTERN_COLOR_R:
1977 case V4L2_CID_TEST_PATTERN_COLOR_GR:
1978 case V4L2_CID_TEST_PATTERN_COLOR_GB:
1979 case V4L2_CID_TEST_PATTERN_COLOR_B:
1980 return v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->
1981 ctrl_handler, control);
1982 case V4L2_CID_COLORFX:
1983 ret = atomisp_color_effect(asd, 0, &control->value);
1985 case V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION:
1986 ret = atomisp_bad_pixel(asd, 0, &control->value);
1988 case V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC:
1989 ret = atomisp_gdc_cac(asd, 0, &control->value);
1991 case V4L2_CID_ATOMISP_VIDEO_STABLIZATION:
1992 ret = atomisp_video_stable(asd, 0, &control->value);
1994 case V4L2_CID_ATOMISP_FIXED_PATTERN_NR:
1995 ret = atomisp_fixed_pattern(asd, 0, &control->value);
1997 case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION:
1998 ret = atomisp_false_color(asd, 0, &control->value);
2000 case V4L2_CID_ATOMISP_LOW_LIGHT:
2001 ret = atomisp_low_light(asd, 0, &control->value);
2012 * To change the value of a control.
2013 * applications initialize the id and value fields of a struct v4l2_control
2014 * and call this ioctl.
2016 static int atomisp_s_ctrl(struct file *file, void *fh,
2017 struct v4l2_control *control)
2019 struct video_device *vdev = video_devdata(file);
2020 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2021 struct atomisp_device *isp = video_get_drvdata(vdev);
2022 int i, ret = -EINVAL;
2024 for (i = 0; i < ctrls_num; i++) {
2025 if (ci_v4l2_controls[i].id == control->id) {
2034 switch (control->id) {
2035 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
2036 case V4L2_CID_EXPOSURE:
2037 case V4L2_CID_EXPOSURE_AUTO:
2038 case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
2039 case V4L2_CID_SCENE_MODE:
2040 case V4L2_CID_ISO_SENSITIVITY:
2041 case V4L2_CID_ISO_SENSITIVITY_AUTO:
2042 case V4L2_CID_POWER_LINE_FREQUENCY:
2043 case V4L2_CID_EXPOSURE_METERING:
2044 case V4L2_CID_CONTRAST:
2045 case V4L2_CID_SATURATION:
2046 case V4L2_CID_SHARPNESS:
2047 case V4L2_CID_3A_LOCK:
2048 case V4L2_CID_COLORFX_CBCR:
2049 case V4L2_CID_TEST_PATTERN:
2050 case V4L2_CID_TEST_PATTERN_COLOR_R:
2051 case V4L2_CID_TEST_PATTERN_COLOR_GR:
2052 case V4L2_CID_TEST_PATTERN_COLOR_GB:
2053 case V4L2_CID_TEST_PATTERN_COLOR_B:
2054 return v4l2_s_ctrl(NULL,
2055 isp->inputs[asd->input_curr].camera->
2056 ctrl_handler, control);
2057 case V4L2_CID_COLORFX:
2058 ret = atomisp_color_effect(asd, 1, &control->value);
2060 case V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION:
2061 ret = atomisp_bad_pixel(asd, 1, &control->value);
2063 case V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC:
2064 ret = atomisp_gdc_cac(asd, 1, &control->value);
2066 case V4L2_CID_ATOMISP_VIDEO_STABLIZATION:
2067 ret = atomisp_video_stable(asd, 1, &control->value);
2069 case V4L2_CID_ATOMISP_FIXED_PATTERN_NR:
2070 ret = atomisp_fixed_pattern(asd, 1, &control->value);
2072 case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION:
2073 ret = atomisp_false_color(asd, 1, &control->value);
2075 case V4L2_CID_REQUEST_FLASH:
2076 ret = atomisp_flash_enable(asd, control->value);
2078 case V4L2_CID_ATOMISP_LOW_LIGHT:
2079 ret = atomisp_low_light(asd, 1, &control->value);
2089 * To query the attributes of a control.
2090 * applications set the id field of a struct v4l2_queryctrl and call the
2091 * this ioctl with a pointer to this structure. The driver fills
2092 * the rest of the structure.
2094 static int atomisp_queryctl(struct file *file, void *fh,
2095 struct v4l2_queryctrl *qc)
2097 int i, ret = -EINVAL;
2098 struct video_device *vdev = video_devdata(file);
2099 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2100 struct atomisp_device *isp = video_get_drvdata(vdev);
2103 case V4L2_CID_FOCUS_ABSOLUTE:
2104 case V4L2_CID_FOCUS_RELATIVE:
2105 case V4L2_CID_FOCUS_STATUS:
2107 return v4l2_queryctrl(isp->inputs[asd->input_curr].camera->
2112 return v4l2_queryctrl(isp->motor->ctrl_handler, qc);
2114 return v4l2_queryctrl(isp->inputs[asd->input_curr].
2115 camera->ctrl_handler, qc);
2118 if (qc->id & V4L2_CTRL_FLAG_NEXT_CTRL)
2121 for (i = 0; i < ctrls_num; i++) {
2122 if (ci_v4l2_controls[i].id == qc->id) {
2123 memcpy(qc, &ci_v4l2_controls[i],
2124 sizeof(struct v4l2_queryctrl));
2125 qc->reserved[0] = 0;
2131 qc->flags = V4L2_CTRL_FLAG_DISABLED;
2136 static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh,
2137 struct v4l2_ext_controls *c)
2139 struct video_device *vdev = video_devdata(file);
2140 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2141 struct atomisp_device *isp = video_get_drvdata(vdev);
2142 struct v4l2_subdev *motor;
2143 struct v4l2_control ctrl;
2148 motor = isp->inputs[asd->input_curr].motor;
2152 for (i = 0; i < c->count; i++) {
2153 ctrl.id = c->controls[i].id;
2154 ctrl.value = c->controls[i].value;
2156 case V4L2_CID_EXPOSURE_ABSOLUTE:
2157 case V4L2_CID_EXPOSURE_AUTO:
2158 case V4L2_CID_IRIS_ABSOLUTE:
2159 case V4L2_CID_FNUMBER_ABSOLUTE:
2160 case V4L2_CID_BIN_FACTOR_HORZ:
2161 case V4L2_CID_BIN_FACTOR_VERT:
2162 case V4L2_CID_3A_LOCK:
2163 case V4L2_CID_TEST_PATTERN:
2164 case V4L2_CID_TEST_PATTERN_COLOR_R:
2165 case V4L2_CID_TEST_PATTERN_COLOR_GR:
2166 case V4L2_CID_TEST_PATTERN_COLOR_GB:
2167 case V4L2_CID_TEST_PATTERN_COLOR_B:
2169 * Exposure related control will be handled by sensor
2173 v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->
2174 ctrl_handler, &ctrl);
2176 case V4L2_CID_FOCUS_ABSOLUTE:
2177 case V4L2_CID_FOCUS_RELATIVE:
2178 case V4L2_CID_FOCUS_STATUS:
2179 case V4L2_CID_FOCUS_AUTO:
2181 ret = v4l2_g_ctrl(motor->ctrl_handler, &ctrl);
2183 case V4L2_CID_FLASH_STATUS:
2184 case V4L2_CID_FLASH_INTENSITY:
2185 case V4L2_CID_FLASH_TORCH_INTENSITY:
2186 case V4L2_CID_FLASH_INDICATOR_INTENSITY:
2187 case V4L2_CID_FLASH_TIMEOUT:
2188 case V4L2_CID_FLASH_STROBE:
2189 case V4L2_CID_FLASH_MODE:
2190 case V4L2_CID_FLASH_STATUS_REGISTER:
2193 v4l2_g_ctrl(isp->flash->ctrl_handler,
2196 case V4L2_CID_ZOOM_ABSOLUTE:
2197 ret = atomisp_digital_zoom(asd, 0, &ctrl.value);
2199 case V4L2_CID_G_SKIP_FRAMES:
2200 ret = v4l2_subdev_call(
2201 isp->inputs[asd->input_curr].camera,
2202 sensor, g_skip_frames, (u32 *)&ctrl.value);
2212 c->controls[i].value = ctrl.value;
2217 /* This ioctl allows the application to get multiple controls by class */
2218 static int atomisp_g_ext_ctrls(struct file *file, void *fh,
2219 struct v4l2_ext_controls *c)
2221 struct v4l2_control ctrl;
2225 * input_lock is not need for the Camera related IOCTLs
2226 * The input_lock downgrade the FPS of 3A
2228 ret = atomisp_camera_g_ext_ctrls(file, fh, c);
2232 for (i = 0; i < c->count; i++) {
2233 ctrl.id = c->controls[i].id;
2234 ctrl.value = c->controls[i].value;
2235 ret = atomisp_g_ctrl(file, fh, &ctrl);
2236 c->controls[i].value = ctrl.value;
2245 static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh,
2246 struct v4l2_ext_controls *c)
2248 struct video_device *vdev = video_devdata(file);
2249 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2250 struct atomisp_device *isp = video_get_drvdata(vdev);
2251 struct v4l2_subdev *motor;
2252 struct v4l2_control ctrl;
2257 motor = isp->inputs[asd->input_curr].motor;
2261 for (i = 0; i < c->count; i++) {
2262 struct v4l2_ctrl *ctr;
2264 ctrl.id = c->controls[i].id;
2265 ctrl.value = c->controls[i].value;
2267 case V4L2_CID_EXPOSURE_ABSOLUTE:
2268 case V4L2_CID_EXPOSURE_AUTO:
2269 case V4L2_CID_EXPOSURE_METERING:
2270 case V4L2_CID_IRIS_ABSOLUTE:
2271 case V4L2_CID_FNUMBER_ABSOLUTE:
2272 case V4L2_CID_VCM_TIMING:
2273 case V4L2_CID_VCM_SLEW:
2274 case V4L2_CID_3A_LOCK:
2275 case V4L2_CID_TEST_PATTERN:
2276 case V4L2_CID_TEST_PATTERN_COLOR_R:
2277 case V4L2_CID_TEST_PATTERN_COLOR_GR:
2278 case V4L2_CID_TEST_PATTERN_COLOR_GB:
2279 case V4L2_CID_TEST_PATTERN_COLOR_B:
2280 ret = v4l2_s_ctrl(NULL,
2281 isp->inputs[asd->input_curr].camera->
2282 ctrl_handler, &ctrl);
2284 case V4L2_CID_FOCUS_ABSOLUTE:
2285 case V4L2_CID_FOCUS_RELATIVE:
2286 case V4L2_CID_FOCUS_STATUS:
2287 case V4L2_CID_FOCUS_AUTO:
2289 ret = v4l2_s_ctrl(NULL, motor->ctrl_handler,
2292 ret = v4l2_s_ctrl(NULL,
2293 isp->inputs[asd->input_curr].
2294 camera->ctrl_handler, &ctrl);
2296 case V4L2_CID_FLASH_STATUS:
2297 case V4L2_CID_FLASH_INTENSITY:
2298 case V4L2_CID_FLASH_TORCH_INTENSITY:
2299 case V4L2_CID_FLASH_INDICATOR_INTENSITY:
2300 case V4L2_CID_FLASH_TIMEOUT:
2301 case V4L2_CID_FLASH_STROBE:
2302 case V4L2_CID_FLASH_MODE:
2303 case V4L2_CID_FLASH_STATUS_REGISTER:
2306 v4l2_s_ctrl(NULL, isp->flash->ctrl_handler,
2309 * When flash mode is changed we need to reset
2312 if (ctrl.id == V4L2_CID_FLASH_MODE) {
2313 asd->params.flash_state =
2315 asd->params.num_flash_frames = 0;
2319 case V4L2_CID_ZOOM_ABSOLUTE:
2320 ret = atomisp_digital_zoom(asd, 1, &ctrl.value);
2323 ctr = v4l2_ctrl_find(&asd->ctrl_handler, ctrl.id);
2325 ret = v4l2_ctrl_s_ctrl(ctr, ctrl.value);
2334 c->controls[i].value = ctrl.value;
2339 /* This ioctl allows the application to set multiple controls by class */
2340 static int atomisp_s_ext_ctrls(struct file *file, void *fh,
2341 struct v4l2_ext_controls *c)
2343 struct v4l2_control ctrl;
2347 * input_lock is not need for the Camera related IOCTLs
2348 * The input_lock downgrade the FPS of 3A
2350 ret = atomisp_camera_s_ext_ctrls(file, fh, c);
2354 for (i = 0; i < c->count; i++) {
2355 ctrl.id = c->controls[i].id;
2356 ctrl.value = c->controls[i].value;
2357 ret = atomisp_s_ctrl(file, fh, &ctrl);
2358 c->controls[i].value = ctrl.value;
2368 * vidioc_g/s_param are used to switch isp running mode
2370 static int atomisp_g_parm(struct file *file, void *fh,
2371 struct v4l2_streamparm *parm)
2373 struct video_device *vdev = video_devdata(file);
2374 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2375 struct atomisp_device *isp = video_get_drvdata(vdev);
2377 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2378 dev_err(isp->dev, "unsupported v4l2 buf type\n");
2382 parm->parm.capture.capturemode = asd->run_mode->val;
2387 static int atomisp_s_parm(struct file *file, void *fh,
2388 struct v4l2_streamparm *parm)
2390 struct video_device *vdev = video_devdata(file);
2391 struct atomisp_device *isp = video_get_drvdata(vdev);
2392 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2397 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2398 dev_err(isp->dev, "unsupported v4l2 buf type\n");
2402 asd->high_speed_mode = false;
2403 switch (parm->parm.capture.capturemode) {
2404 case CI_MODE_NONE: {
2405 struct v4l2_subdev_frame_interval fi = {0};
2407 fi.interval = parm->parm.capture.timeperframe;
2409 rval = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2410 video, s_frame_interval, &fi);
2412 parm->parm.capture.timeperframe = fi.interval;
2414 if (fi.interval.numerator != 0) {
2415 fps = fi.interval.denominator / fi.interval.numerator;
2417 asd->high_speed_mode = true;
2420 return rval == -ENOIOCTLCMD ? 0 : rval;
2423 mode = ATOMISP_RUN_MODE_VIDEO;
2425 case CI_MODE_STILL_CAPTURE:
2426 mode = ATOMISP_RUN_MODE_STILL_CAPTURE;
2428 case CI_MODE_CONTINUOUS:
2429 mode = ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE;
2431 case CI_MODE_PREVIEW:
2432 mode = ATOMISP_RUN_MODE_PREVIEW;
2438 rval = v4l2_ctrl_s_ctrl(asd->run_mode, mode);
2440 return rval == -ENOIOCTLCMD ? 0 : rval;
2443 static long atomisp_vidioc_default(struct file *file, void *fh,
2444 bool valid_prio, unsigned int cmd, void *arg)
2446 struct video_device *vdev = video_devdata(file);
2447 struct atomisp_device *isp = video_get_drvdata(vdev);
2448 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2449 struct v4l2_subdev *motor;
2453 motor = isp->inputs[asd->input_curr].motor;
2458 case ATOMISP_IOC_S_SENSOR_RUNMODE:
2460 err = atomisp_set_sensor_runmode(asd, arg);
2465 case ATOMISP_IOC_G_XNR:
2466 err = atomisp_xnr(asd, 0, arg);
2469 case ATOMISP_IOC_S_XNR:
2470 err = atomisp_xnr(asd, 1, arg);
2473 case ATOMISP_IOC_G_NR:
2474 err = atomisp_nr(asd, 0, arg);
2477 case ATOMISP_IOC_S_NR:
2478 err = atomisp_nr(asd, 1, arg);
2481 case ATOMISP_IOC_G_TNR:
2482 err = atomisp_tnr(asd, 0, arg);
2485 case ATOMISP_IOC_S_TNR:
2486 err = atomisp_tnr(asd, 1, arg);
2489 case ATOMISP_IOC_G_BLACK_LEVEL_COMP:
2490 err = atomisp_black_level(asd, 0, arg);
2493 case ATOMISP_IOC_S_BLACK_LEVEL_COMP:
2494 err = atomisp_black_level(asd, 1, arg);
2497 case ATOMISP_IOC_G_EE:
2498 err = atomisp_ee(asd, 0, arg);
2501 case ATOMISP_IOC_S_EE:
2502 err = atomisp_ee(asd, 1, arg);
2505 case ATOMISP_IOC_G_DIS_STAT:
2506 err = atomisp_get_dis_stat(asd, arg);
2509 case ATOMISP_IOC_G_DVS2_BQ_RESOLUTIONS:
2510 err = atomisp_get_dvs2_bq_resolutions(asd, arg);
2513 case ATOMISP_IOC_S_DIS_COEFS:
2514 err = atomisp_css_cp_dvs2_coefs(asd, arg,
2515 &asd->params.css_param, true);
2517 asd->params.css_update_params_needed = true;
2520 case ATOMISP_IOC_S_DIS_VECTOR:
2521 err = atomisp_cp_dvs_6axis_config(asd, arg,
2522 &asd->params.css_param, true);
2524 asd->params.css_update_params_needed = true;
2527 case ATOMISP_IOC_G_ISP_PARM:
2528 err = atomisp_param(asd, 0, arg);
2531 case ATOMISP_IOC_S_ISP_PARM:
2532 err = atomisp_param(asd, 1, arg);
2535 case ATOMISP_IOC_G_3A_STAT:
2536 err = atomisp_3a_stat(asd, 0, arg);
2539 case ATOMISP_IOC_G_ISP_GAMMA:
2540 err = atomisp_gamma(asd, 0, arg);
2543 case ATOMISP_IOC_S_ISP_GAMMA:
2544 err = atomisp_gamma(asd, 1, arg);
2547 case ATOMISP_IOC_G_ISP_GDC_TAB:
2548 err = atomisp_gdc_cac_table(asd, 0, arg);
2551 case ATOMISP_IOC_S_ISP_GDC_TAB:
2552 err = atomisp_gdc_cac_table(asd, 1, arg);
2555 case ATOMISP_IOC_G_ISP_MACC:
2556 err = atomisp_macc_table(asd, 0, arg);
2559 case ATOMISP_IOC_S_ISP_MACC:
2560 err = atomisp_macc_table(asd, 1, arg);
2563 case ATOMISP_IOC_G_ISP_BAD_PIXEL_DETECTION:
2564 err = atomisp_bad_pixel_param(asd, 0, arg);
2567 case ATOMISP_IOC_S_ISP_BAD_PIXEL_DETECTION:
2568 err = atomisp_bad_pixel_param(asd, 1, arg);
2571 case ATOMISP_IOC_G_ISP_FALSE_COLOR_CORRECTION:
2572 err = atomisp_false_color_param(asd, 0, arg);
2575 case ATOMISP_IOC_S_ISP_FALSE_COLOR_CORRECTION:
2576 err = atomisp_false_color_param(asd, 1, arg);
2579 case ATOMISP_IOC_G_ISP_CTC:
2580 err = atomisp_ctc(asd, 0, arg);
2583 case ATOMISP_IOC_S_ISP_CTC:
2584 err = atomisp_ctc(asd, 1, arg);
2587 case ATOMISP_IOC_G_ISP_WHITE_BALANCE:
2588 err = atomisp_white_balance_param(asd, 0, arg);
2591 case ATOMISP_IOC_S_ISP_WHITE_BALANCE:
2592 err = atomisp_white_balance_param(asd, 1, arg);
2595 case ATOMISP_IOC_G_3A_CONFIG:
2596 err = atomisp_3a_config_param(asd, 0, arg);
2599 case ATOMISP_IOC_S_3A_CONFIG:
2600 err = atomisp_3a_config_param(asd, 1, arg);
2603 case ATOMISP_IOC_S_ISP_FPN_TABLE:
2604 err = atomisp_fixed_pattern_table(asd, arg);
2607 case ATOMISP_IOC_ISP_MAKERNOTE:
2608 err = atomisp_exif_makernote(asd, arg);
2611 case ATOMISP_IOC_G_SENSOR_MODE_DATA:
2612 err = atomisp_get_sensor_mode_data(asd, arg);
2615 case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
2617 err = v4l2_subdev_call(motor, core, ioctl, cmd, arg);
2619 err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2620 core, ioctl, cmd, arg);
2623 case ATOMISP_IOC_S_EXPOSURE:
2624 case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
2625 case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
2626 case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO:
2627 case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE:
2628 case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE:
2629 case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT:
2630 err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2631 core, ioctl, cmd, arg);
2633 case ATOMISP_IOC_G_UPDATE_EXPOSURE:
2635 err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2636 core, ioctl, cmd, arg);
2641 case ATOMISP_IOC_S_ISP_SHD_TAB:
2642 err = atomisp_set_shading_table(asd, arg);
2645 case ATOMISP_IOC_G_ISP_GAMMA_CORRECTION:
2646 err = atomisp_gamma_correction(asd, 0, arg);
2649 case ATOMISP_IOC_S_ISP_GAMMA_CORRECTION:
2650 err = atomisp_gamma_correction(asd, 1, arg);
2653 case ATOMISP_IOC_S_PARAMETERS:
2654 err = atomisp_set_parameters(vdev, arg);
2657 case ATOMISP_IOC_S_CONT_CAPTURE_CONFIG:
2658 err = atomisp_offline_capture_configure(asd, arg);
2660 case ATOMISP_IOC_G_METADATA:
2661 err = atomisp_get_metadata(asd, 0, arg);
2663 case ATOMISP_IOC_G_METADATA_BY_TYPE:
2664 err = atomisp_get_metadata_by_type(asd, 0, arg);
2666 case ATOMISP_IOC_EXT_ISP_CTRL:
2667 err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2668 core, ioctl, cmd, arg);
2670 case ATOMISP_IOC_EXP_ID_UNLOCK:
2671 err = atomisp_exp_id_unlock(asd, arg);
2673 case ATOMISP_IOC_EXP_ID_CAPTURE:
2674 err = atomisp_exp_id_capture(asd, arg);
2676 case ATOMISP_IOC_S_ENABLE_DZ_CAPT_PIPE:
2677 err = atomisp_enable_dz_capt_pipe(asd, arg);
2679 case ATOMISP_IOC_G_FORMATS_CONFIG:
2680 err = atomisp_formats(asd, 0, arg);
2683 case ATOMISP_IOC_S_FORMATS_CONFIG:
2684 err = atomisp_formats(asd, 1, arg);
2686 case ATOMISP_IOC_S_EXPOSURE_WINDOW:
2687 err = atomisp_s_ae_window(asd, arg);
2689 case ATOMISP_IOC_INJECT_A_FAKE_EVENT:
2690 err = atomisp_inject_a_fake_event(asd, arg);
2692 case ATOMISP_IOC_G_INVALID_FRAME_NUM:
2693 err = atomisp_get_invalid_frame_num(vdev, arg);
2695 case ATOMISP_IOC_S_ARRAY_RESOLUTION:
2696 err = atomisp_set_array_res(asd, arg);
2706 const struct v4l2_ioctl_ops atomisp_ioctl_ops = {
2707 .vidioc_querycap = atomisp_querycap,
2708 .vidioc_enum_input = atomisp_enum_input,
2709 .vidioc_g_input = atomisp_g_input,
2710 .vidioc_s_input = atomisp_s_input,
2711 .vidioc_queryctrl = atomisp_queryctl,
2712 .vidioc_s_ctrl = atomisp_s_ctrl,
2713 .vidioc_g_ctrl = atomisp_g_ctrl,
2714 .vidioc_s_ext_ctrls = atomisp_s_ext_ctrls,
2715 .vidioc_g_ext_ctrls = atomisp_g_ext_ctrls,
2716 .vidioc_enum_framesizes = atomisp_enum_framesizes,
2717 .vidioc_enum_frameintervals = atomisp_enum_frameintervals,
2718 .vidioc_enum_fmt_vid_cap = atomisp_enum_fmt_cap,
2719 .vidioc_try_fmt_vid_cap = atomisp_try_fmt_cap,
2720 .vidioc_g_fmt_vid_cap = atomisp_g_fmt_cap,
2721 .vidioc_s_fmt_vid_cap = atomisp_set_fmt,
2722 .vidioc_reqbufs = atomisp_reqbufs,
2723 .vidioc_querybuf = atomisp_querybuf,
2724 .vidioc_qbuf = atomisp_qbuf,
2725 .vidioc_dqbuf = atomisp_dqbuf,
2726 .vidioc_streamon = atomisp_streamon,
2727 .vidioc_streamoff = atomisp_streamoff,
2728 .vidioc_default = atomisp_vidioc_default,
2729 .vidioc_s_parm = atomisp_s_parm,
2730 .vidioc_g_parm = atomisp_g_parm,