linux/drivers/staging/media/atomisp/pci/atomisp_ioctl.c
<<
>>
Prefs
   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#include <media/videobuf-vmalloc.h>
  27
  28#include "atomisp_acc.h"
  29#include "atomisp_cmd.h"
  30#include "atomisp_common.h"
  31#include "atomisp_fops.h"
  32#include "atomisp_internal.h"
  33#include "atomisp_ioctl.h"
  34#include "atomisp-regs.h"
  35#include "atomisp_compat.h"
  36
  37#include "sh_css_hrt.h"
  38
  39#include "gp_device.h"
  40#include "device_access.h"
  41#include "irq.h"
  42
  43static const char *DRIVER = "atomisp";  /* max size 15 */
  44static const char *CARD = "ATOM ISP";   /* max size 31 */
  45
  46/*
  47 * FIXME: ISP should not know beforehand all CIDs supported by sensor.
  48 * Instead, it needs to propagate to sensor unkonwn CIDs.
  49 */
  50static struct v4l2_queryctrl ci_v4l2_controls[] = {
  51        {
  52                .id = V4L2_CID_AUTO_WHITE_BALANCE,
  53                .type = V4L2_CTRL_TYPE_BOOLEAN,
  54                .name = "Automatic White Balance",
  55                .minimum = 0,
  56                .maximum = 1,
  57                .step = 1,
  58                .default_value = 0,
  59        },
  60        {
  61                .id = V4L2_CID_RED_BALANCE,
  62                .type = V4L2_CTRL_TYPE_INTEGER,
  63                .name = "Red Balance",
  64                .minimum = 0x00,
  65                .maximum = 0xff,
  66                .step = 1,
  67                .default_value = 0x00,
  68        },
  69        {
  70                .id = V4L2_CID_BLUE_BALANCE,
  71                .type = V4L2_CTRL_TYPE_INTEGER,
  72                .name = "Blue Balance",
  73                .minimum = 0x00,
  74                .maximum = 0xff,
  75                .step = 1,
  76                .default_value = 0x00,
  77        },
  78        {
  79                .id = V4L2_CID_GAMMA,
  80                .type = V4L2_CTRL_TYPE_INTEGER,
  81                .name = "Gamma",
  82                .minimum = 0x00,
  83                .maximum = 0xff,
  84                .step = 1,
  85                .default_value = 0x00,
  86        },
  87        {
  88                .id = V4L2_CID_POWER_LINE_FREQUENCY,
  89                .type = V4L2_CTRL_TYPE_MENU,
  90                .name = "Light frequency filter",
  91                .minimum = 1,
  92                .maximum = 2,
  93                .step = 1,
  94                .default_value = 1,
  95        },
  96        {
  97                .id = V4L2_CID_COLORFX,
  98                .type = V4L2_CTRL_TYPE_INTEGER,
  99                .name = "Image Color Effect",
 100                .minimum = 0,
 101                .maximum = 9,
 102                .step = 1,
 103                .default_value = 0,
 104        },
 105        {
 106                .id = V4L2_CID_COLORFX_CBCR,
 107                .type = V4L2_CTRL_TYPE_INTEGER,
 108                .name = "Image Color Effect CbCr",
 109                .minimum = 0,
 110                .maximum = 0xffff,
 111                .step = 1,
 112                .default_value = 0,
 113        },
 114        {
 115                .id = V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION,
 116                .type = V4L2_CTRL_TYPE_INTEGER,
 117                .name = "Bad Pixel Correction",
 118                .minimum = 0,
 119                .maximum = 1,
 120                .step = 1,
 121                .default_value = 0,
 122        },
 123        {
 124                .id = V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC,
 125                .type = V4L2_CTRL_TYPE_INTEGER,
 126                .name = "GDC/CAC",
 127                .minimum = 0,
 128                .maximum = 1,
 129                .step = 1,
 130                .default_value = 0,
 131        },
 132        {
 133                .id = V4L2_CID_ATOMISP_VIDEO_STABLIZATION,
 134                .type = V4L2_CTRL_TYPE_INTEGER,
 135                .name = "Video Stablization",
 136                .minimum = 0,
 137                .maximum = 1,
 138                .step = 1,
 139                .default_value = 0,
 140        },
 141        {
 142                .id = V4L2_CID_ATOMISP_FIXED_PATTERN_NR,
 143                .type = V4L2_CTRL_TYPE_INTEGER,
 144                .name = "Fixed Pattern Noise Reduction",
 145                .minimum = 0,
 146                .maximum = 1,
 147                .step = 1,
 148                .default_value = 0,
 149        },
 150        {
 151                .id = V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION,
 152                .type = V4L2_CTRL_TYPE_INTEGER,
 153                .name = "False Color Correction",
 154                .minimum = 0,
 155                .maximum = 1,
 156                .step = 1,
 157                .default_value = 0,
 158        },
 159        {
 160                .id = V4L2_CID_REQUEST_FLASH,
 161                .type = V4L2_CTRL_TYPE_INTEGER,
 162                .name = "Request flash frames",
 163                .minimum = 0,
 164                .maximum = 10,
 165                .step = 1,
 166                .default_value = 1,
 167        },
 168        {
 169                .id = V4L2_CID_ATOMISP_LOW_LIGHT,
 170                .type = V4L2_CTRL_TYPE_BOOLEAN,
 171                .name = "Low light mode",
 172                .minimum = 0,
 173                .maximum = 1,
 174                .step = 1,
 175                .default_value = 1,
 176        },
 177        {
 178                .id = V4L2_CID_BIN_FACTOR_HORZ,
 179                .type = V4L2_CTRL_TYPE_INTEGER,
 180                .name = "Horizontal binning factor",
 181                .minimum = 0,
 182                .maximum = 10,
 183                .step = 1,
 184                .default_value = 0,
 185        },
 186        {
 187                .id = V4L2_CID_BIN_FACTOR_VERT,
 188                .type = V4L2_CTRL_TYPE_INTEGER,
 189                .name = "Vertical binning factor",
 190                .minimum = 0,
 191                .maximum = 10,
 192                .step = 1,
 193                .default_value = 0,
 194        },
 195        {
 196                .id = V4L2_CID_2A_STATUS,
 197                .type = V4L2_CTRL_TYPE_BITMASK,
 198                .name = "AE and AWB status",
 199                .minimum = 0,
 200                .maximum = V4L2_2A_STATUS_AE_READY | V4L2_2A_STATUS_AWB_READY,
 201                .step = 1,
 202                .default_value = 0,
 203        },
 204        {
 205                .id = V4L2_CID_EXPOSURE,
 206                .type = V4L2_CTRL_TYPE_INTEGER,
 207                .name = "exposure",
 208                .minimum = -4,
 209                .maximum = 4,
 210                .step = 1,
 211                .default_value = 0,
 212        },
 213        {
 214                .id = V4L2_CID_EXPOSURE_ZONE_NUM,
 215                .type = V4L2_CTRL_TYPE_INTEGER,
 216                .name = "one-time exposure zone number",
 217                .minimum = 0x0,
 218                .maximum = 0xffff,
 219                .step = 1,
 220                .default_value = 0,
 221        },
 222        {
 223                .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
 224                .type = V4L2_CTRL_TYPE_INTEGER,
 225                .name = "Exposure auto priority",
 226                .minimum = V4L2_EXPOSURE_AUTO,
 227                .maximum = V4L2_EXPOSURE_APERTURE_PRIORITY,
 228                .step = 1,
 229                .default_value = V4L2_EXPOSURE_AUTO,
 230        },
 231        {
 232                .id = V4L2_CID_SCENE_MODE,
 233                .type = V4L2_CTRL_TYPE_INTEGER,
 234                .name = "scene mode",
 235                .minimum = 0,
 236                .maximum = 13,
 237                .step = 1,
 238                .default_value = 0,
 239        },
 240        {
 241                .id = V4L2_CID_ISO_SENSITIVITY,
 242                .type = V4L2_CTRL_TYPE_INTEGER,
 243                .name = "iso",
 244                .minimum = -4,
 245                .maximum = 4,
 246                .step = 1,
 247                .default_value = 0,
 248        },
 249        {
 250                .id = V4L2_CID_ISO_SENSITIVITY_AUTO,
 251                .type = V4L2_CTRL_TYPE_INTEGER,
 252                .name = "iso mode",
 253                .minimum = V4L2_ISO_SENSITIVITY_MANUAL,
 254                .maximum = V4L2_ISO_SENSITIVITY_AUTO,
 255                .step = 1,
 256                .default_value = V4L2_ISO_SENSITIVITY_AUTO,
 257        },
 258        {
 259                .id = V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
 260                .type = V4L2_CTRL_TYPE_INTEGER,
 261                .name = "white balance",
 262                .minimum = 0,
 263                .maximum = 9,
 264                .step = 1,
 265                .default_value = 0,
 266        },
 267        {
 268                .id = V4L2_CID_EXPOSURE_METERING,
 269                .type = V4L2_CTRL_TYPE_MENU,
 270                .name = "metering",
 271                .minimum = 0,
 272                .maximum = 3,
 273                .step = 1,
 274                .default_value = 1,
 275        },
 276        {
 277                .id = V4L2_CID_3A_LOCK,
 278                .type = V4L2_CTRL_TYPE_BITMASK,
 279                .name = "3a lock",
 280                .minimum = 0,
 281                .maximum = V4L2_LOCK_EXPOSURE | V4L2_LOCK_WHITE_BALANCE
 282                | V4L2_LOCK_FOCUS,
 283                .step = 1,
 284                .default_value = 0,
 285        },
 286        {
 287                .id = V4L2_CID_TEST_PATTERN,
 288                .type = V4L2_CTRL_TYPE_INTEGER,
 289                .name = "Test Pattern",
 290                .minimum = 0,
 291                .maximum = 0xffff,
 292                .step = 1,
 293                .default_value = 0,
 294        },
 295        {
 296                .id = V4L2_CID_TEST_PATTERN_COLOR_R,
 297                .type = V4L2_CTRL_TYPE_INTEGER,
 298                .name = "Test Pattern Solid Color R",
 299                .minimum = INT_MIN,
 300                .maximum = INT_MAX,
 301                .step = 1,
 302                .default_value = 0,
 303        },
 304        {
 305                .id = V4L2_CID_TEST_PATTERN_COLOR_GR,
 306                .type = V4L2_CTRL_TYPE_INTEGER,
 307                .name = "Test Pattern Solid Color GR",
 308                .minimum = INT_MIN,
 309                .maximum = INT_MAX,
 310                .step = 1,
 311                .default_value = 0,
 312        },
 313        {
 314                .id = V4L2_CID_TEST_PATTERN_COLOR_GB,
 315                .type = V4L2_CTRL_TYPE_INTEGER,
 316                .name = "Test Pattern Solid Color GB",
 317                .minimum = INT_MIN,
 318                .maximum = INT_MAX,
 319                .step = 1,
 320                .default_value = 0,
 321        },
 322        {
 323                .id = V4L2_CID_TEST_PATTERN_COLOR_B,
 324                .type = V4L2_CTRL_TYPE_INTEGER,
 325                .name = "Test Pattern Solid Color B",
 326                .minimum = INT_MIN,
 327                .maximum = INT_MAX,
 328                .step = 1,
 329                .default_value = 0,
 330        },
 331};
 332
 333static const u32 ctrls_num = ARRAY_SIZE(ci_v4l2_controls);
 334
 335/*
 336 * supported V4L2 fmts and resolutions
 337 */
 338const struct atomisp_format_bridge atomisp_output_fmts[] = {
 339        {
 340                .pixelformat = V4L2_PIX_FMT_YUV420,
 341                .depth = 12,
 342                .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV420,
 343                .sh_fmt = IA_CSS_FRAME_FORMAT_YUV420,
 344                .description = "YUV420, planar",
 345                .planar = true
 346        }, {
 347                .pixelformat = V4L2_PIX_FMT_YVU420,
 348                .depth = 12,
 349                .mbus_code = V4L2_MBUS_FMT_CUSTOM_YVU420,
 350                .sh_fmt = IA_CSS_FRAME_FORMAT_YV12,
 351                .description = "YVU420, planar",
 352                .planar = true
 353        }, {
 354                .pixelformat = V4L2_PIX_FMT_YUV422P,
 355                .depth = 16,
 356                .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV422P,
 357                .sh_fmt = IA_CSS_FRAME_FORMAT_YUV422,
 358                .description = "YUV422, planar",
 359                .planar = true
 360        }, {
 361                .pixelformat = V4L2_PIX_FMT_YUV444,
 362                .depth = 24,
 363                .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV444,
 364                .sh_fmt = IA_CSS_FRAME_FORMAT_YUV444,
 365                .description = "YUV444"
 366        }, {
 367                .pixelformat = V4L2_PIX_FMT_NV12,
 368                .depth = 12,
 369                .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV12,
 370                .sh_fmt = IA_CSS_FRAME_FORMAT_NV12,
 371                .description = "NV12, Y-plane, CbCr interleaved",
 372                .planar = true
 373        }, {
 374                .pixelformat = V4L2_PIX_FMT_NV21,
 375                .depth = 12,
 376                .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV21,
 377                .sh_fmt = IA_CSS_FRAME_FORMAT_NV21,
 378                .description = "NV21, Y-plane, CbCr interleaved",
 379                .planar = true
 380        }, {
 381                .pixelformat = V4L2_PIX_FMT_NV16,
 382                .depth = 16,
 383                .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV16,
 384                .sh_fmt = IA_CSS_FRAME_FORMAT_NV16,
 385                .description = "NV16, Y-plane, CbCr interleaved",
 386                .planar = true
 387        }, {
 388                .pixelformat = V4L2_PIX_FMT_YUYV,
 389                .depth = 16,
 390                .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUYV,
 391                .sh_fmt = IA_CSS_FRAME_FORMAT_YUYV,
 392                .description = "YUYV, interleaved"
 393        }, {
 394                .pixelformat = V4L2_PIX_FMT_UYVY,
 395                .depth = 16,
 396                .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
 397                .sh_fmt = IA_CSS_FRAME_FORMAT_UYVY,
 398                .description = "UYVY, interleaved"
 399        }, { /* This one is for parallel sensors! DO NOT USE! */
 400                .pixelformat = V4L2_PIX_FMT_UYVY,
 401                .depth = 16,
 402                .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
 403                .sh_fmt = IA_CSS_FRAME_FORMAT_UYVY,
 404                .description = "UYVY, interleaved"
 405        }, {
 406                .pixelformat = V4L2_PIX_FMT_SBGGR16,
 407                .depth = 16,
 408                .mbus_code = V4L2_MBUS_FMT_CUSTOM_SBGGR16,
 409                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 410                .description = "Bayer 16"
 411        }, {
 412                .pixelformat = V4L2_PIX_FMT_SBGGR8,
 413                .depth = 8,
 414                .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
 415                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 416                .description = "Bayer 8"
 417        }, {
 418                .pixelformat = V4L2_PIX_FMT_SGBRG8,
 419                .depth = 8,
 420                .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
 421                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 422                .description = "Bayer 8"
 423        }, {
 424                .pixelformat = V4L2_PIX_FMT_SGRBG8,
 425                .depth = 8,
 426                .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
 427                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 428                .description = "Bayer 8"
 429        }, {
 430                .pixelformat = V4L2_PIX_FMT_SRGGB8,
 431                .depth = 8,
 432                .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
 433                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 434                .description = "Bayer 8"
 435        }, {
 436                .pixelformat = V4L2_PIX_FMT_SBGGR10,
 437                .depth = 16,
 438                .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
 439                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 440                .description = "Bayer 10"
 441        }, {
 442                .pixelformat = V4L2_PIX_FMT_SGBRG10,
 443                .depth = 16,
 444                .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
 445                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 446                .description = "Bayer 10"
 447        }, {
 448                .pixelformat = V4L2_PIX_FMT_SGRBG10,
 449                .depth = 16,
 450                .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
 451                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 452                .description = "Bayer 10"
 453        }, {
 454                .pixelformat = V4L2_PIX_FMT_SRGGB10,
 455                .depth = 16,
 456                .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
 457                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 458                .description = "Bayer 10"
 459        }, {
 460                .pixelformat = V4L2_PIX_FMT_SBGGR12,
 461                .depth = 16,
 462                .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
 463                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 464                .description = "Bayer 12"
 465        }, {
 466                .pixelformat = V4L2_PIX_FMT_SGBRG12,
 467                .depth = 16,
 468                .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
 469                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 470                .description = "Bayer 12"
 471        }, {
 472                .pixelformat = V4L2_PIX_FMT_SGRBG12,
 473                .depth = 16,
 474                .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
 475                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 476                .description = "Bayer 12"
 477        }, {
 478                .pixelformat = V4L2_PIX_FMT_SRGGB12,
 479                .depth = 16,
 480                .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
 481                .sh_fmt = IA_CSS_FRAME_FORMAT_RAW,
 482                .description = "Bayer 12"
 483        }, {
 484                .pixelformat = V4L2_PIX_FMT_RGB32,
 485                .depth = 32,
 486                .mbus_code = V4L2_MBUS_FMT_CUSTOM_RGB32,
 487                .sh_fmt = IA_CSS_FRAME_FORMAT_RGBA888,
 488                .description = "32 RGB 8-8-8-8"
 489        }, {
 490                .pixelformat = V4L2_PIX_FMT_RGB565,
 491                .depth = 16,
 492                .mbus_code = MEDIA_BUS_FMT_BGR565_2X8_LE,
 493                .sh_fmt = IA_CSS_FRAME_FORMAT_RGB565,
 494                .description = "16 RGB 5-6-5"
 495        }, {
 496                .pixelformat = V4L2_PIX_FMT_JPEG,
 497                .depth = 8,
 498                .mbus_code = MEDIA_BUS_FMT_JPEG_1X8,
 499                .sh_fmt = IA_CSS_FRAME_FORMAT_BINARY_8,
 500                .description = "JPEG"
 501        },
 502#if 0
 503        {
 504                /* This is a custom format being used by M10MO to send the RAW data */
 505                .pixelformat = V4L2_PIX_FMT_CUSTOM_M10MO_RAW,
 506                .depth = 8,
 507                .mbus_code = V4L2_MBUS_FMT_CUSTOM_M10MO_RAW,
 508                .sh_fmt = IA_CSS_FRAME_FORMAT_BINARY_8,
 509                .description = "Custom RAW for M10MO"
 510        },
 511#endif
 512};
 513
 514const struct atomisp_format_bridge *
 515atomisp_get_format_bridge(unsigned int pixelformat)
 516{
 517        unsigned int i;
 518
 519        for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
 520                if (atomisp_output_fmts[i].pixelformat == pixelformat)
 521                        return &atomisp_output_fmts[i];
 522        }
 523
 524        return NULL;
 525}
 526
 527const struct atomisp_format_bridge *
 528atomisp_get_format_bridge_from_mbus(u32 mbus_code)
 529{
 530        unsigned int i;
 531
 532        for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
 533                if (mbus_code == atomisp_output_fmts[i].mbus_code)
 534                        return &atomisp_output_fmts[i];
 535        }
 536
 537        return NULL;
 538}
 539
 540/*
 541 * v4l2 ioctls
 542 * return ISP capabilities
 543 */
 544static int atomisp_querycap(struct file *file, void *fh,
 545                            struct v4l2_capability *cap)
 546{
 547        struct video_device *vdev = video_devdata(file);
 548        struct atomisp_device *isp = video_get_drvdata(vdev);
 549
 550        strscpy(cap->driver, DRIVER, sizeof(cap->driver));
 551        strscpy(cap->card, CARD, sizeof(cap->card));
 552        snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", dev_name(isp->dev));
 553
 554        return 0;
 555}
 556
 557/*
 558 * enum input are used to check primary/secondary camera
 559 */
 560static int atomisp_enum_input(struct file *file, void *fh,
 561                              struct v4l2_input *input)
 562{
 563        struct video_device *vdev = video_devdata(file);
 564        struct atomisp_device *isp = video_get_drvdata(vdev);
 565        int index = input->index;
 566        struct v4l2_subdev *motor;
 567
 568        if (index >= isp->input_cnt)
 569                return -EINVAL;
 570
 571        if (!isp->inputs[index].camera)
 572                return -EINVAL;
 573
 574        memset(input, 0, sizeof(struct v4l2_input));
 575        strscpy(input->name, isp->inputs[index].camera->name,
 576                sizeof(input->name));
 577
 578        /*
 579         * HACK: append actuator's name to sensor's
 580         * As currently userspace can't talk directly to subdev nodes, this
 581         * ioctl is the only way to enum inputs + possible external actuators
 582         * for 3A tuning purpose.
 583         */
 584        if (!IS_ISP2401)
 585                motor = isp->inputs[index].motor;
 586        else
 587                motor = isp->motor;
 588
 589        if (motor && strlen(motor->name) > 0) {
 590                const int cur_len = strlen(input->name);
 591                const int max_size = sizeof(input->name) - cur_len - 1;
 592
 593                if (max_size > 1) {
 594                        input->name[cur_len] = '+';
 595                        strscpy(&input->name[cur_len + 1],
 596                                motor->name, max_size);
 597                }
 598        }
 599
 600        input->type = V4L2_INPUT_TYPE_CAMERA;
 601        input->index = index;
 602        input->reserved[0] = isp->inputs[index].type;
 603        input->reserved[1] = isp->inputs[index].port;
 604
 605        return 0;
 606}
 607
 608static unsigned int
 609atomisp_subdev_streaming_count(struct atomisp_sub_device *asd)
 610{
 611        return asd->video_out_preview.capq.streaming
 612               + asd->video_out_capture.capq.streaming
 613               + asd->video_out_video_capture.capq.streaming
 614               + asd->video_out_vf.capq.streaming
 615               + asd->video_in.capq.streaming;
 616}
 617
 618unsigned int atomisp_streaming_count(struct atomisp_device *isp)
 619{
 620        unsigned int i, sum;
 621
 622        for (i = 0, sum = 0; i < isp->num_of_streams; i++)
 623                sum += isp->asd[i].streaming ==
 624                       ATOMISP_DEVICE_STREAMING_ENABLED;
 625
 626        return sum;
 627}
 628
 629unsigned int atomisp_is_acc_enabled(struct atomisp_device *isp)
 630{
 631        unsigned int i;
 632
 633        for (i = 0; i < isp->num_of_streams; i++)
 634                if (isp->asd[i].acc.pipeline)
 635                        return 1;
 636
 637        return 0;
 638}
 639
 640/*
 641 * get input are used to get current primary/secondary camera
 642 */
 643static int atomisp_g_input(struct file *file, void *fh, unsigned int *input)
 644{
 645        struct video_device *vdev = video_devdata(file);
 646        struct atomisp_device *isp = video_get_drvdata(vdev);
 647        struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
 648
 649        rt_mutex_lock(&isp->mutex);
 650        *input = asd->input_curr;
 651        rt_mutex_unlock(&isp->mutex);
 652
 653        return 0;
 654}
 655
 656/*
 657 * set input are used to set current primary/secondary camera
 658 */
 659static int atomisp_s_input(struct file *file, void *fh, unsigned int input)
 660{
 661        struct video_device *vdev = video_devdata(file);
 662        struct atomisp_device *isp = video_get_drvdata(vdev);
 663        struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
 664        struct v4l2_subdev *camera = NULL;
 665        struct v4l2_subdev *motor;
 666        int ret;
 667
 668        rt_mutex_lock(&isp->mutex);
 669        if (input >= ATOM_ISP_MAX_INPUTS || input >= isp->input_cnt) {
 670                dev_dbg(isp->dev, "input_cnt: %d\n", isp->input_cnt);
 671                ret = -EINVAL;
 672                goto error;
 673        }
 674
 675        /*
 676         * check whether the request camera:
 677         * 1: already in use
 678         * 2: if in use, whether it is used by other streams
 679         */
 680        if (isp->inputs[input].asd && isp->inputs[input].asd != asd) {
 681                dev_err(isp->dev,
 682                        "%s, camera is already used by stream: %d\n", __func__,
 683                        isp->inputs[input].asd->index);
 684                ret = -EBUSY;
 685                goto error;
 686        }
 687
 688        camera = isp->inputs[input].camera;
 689        if (!camera) {
 690                dev_err(isp->dev, "%s, no camera\n", __func__);
 691                ret = -EINVAL;
 692                goto error;
 693        }
 694
 695        if (atomisp_subdev_streaming_count(asd)) {
 696                dev_err(isp->dev,
 697                        "ISP is still streaming, stop first\n");
 698                ret = -EINVAL;
 699                goto error;
 700        }
 701
 702        /* power off the current owned sensor, as it is not used this time */
 703        if (isp->inputs[asd->input_curr].asd == asd &&
 704            asd->input_curr != input) {
 705                ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
 706                                       core, s_power, 0);
 707                if (ret)
 708                        dev_warn(isp->dev,
 709                                 "Failed to power-off sensor\n");
 710                /* clear the asd field to show this camera is not used */
 711                isp->inputs[asd->input_curr].asd = NULL;
 712        }
 713
 714        /* powe on the new sensor */
 715        ret = v4l2_subdev_call(isp->inputs[input].camera, core, s_power, 1);
 716        if (ret) {
 717                dev_err(isp->dev, "Failed to power-on sensor\n");
 718                goto error;
 719        }
 720        /*
 721         * Some sensor driver resets the run mode during power-on, thus force
 722         * update the run mode to sensor after power-on.
 723         */
 724        atomisp_update_run_mode(asd);
 725
 726        /* select operating sensor */
 727        ret = v4l2_subdev_call(isp->inputs[input].camera, video, s_routing,
 728                               0, isp->inputs[input].sensor_index, 0);
 729        if (ret && (ret != -ENOIOCTLCMD)) {
 730                dev_err(isp->dev, "Failed to select sensor\n");
 731                goto error;
 732        }
 733
 734        if (!IS_ISP2401) {
 735                motor = isp->inputs[input].motor;
 736        } else {
 737                motor = isp->motor;
 738                if (motor)
 739                        ret = v4l2_subdev_call(motor, core, s_power, 1);
 740        }
 741
 742        if (!isp->sw_contex.file_input && motor)
 743                ret = v4l2_subdev_call(motor, core, init, 1);
 744
 745        asd->input_curr = input;
 746        /* mark this camera is used by the current stream */
 747        isp->inputs[input].asd = asd;
 748        rt_mutex_unlock(&isp->mutex);
 749
 750        return 0;
 751
 752error:
 753        rt_mutex_unlock(&isp->mutex);
 754
 755        return ret;
 756}
 757
 758static int atomisp_enum_fmt_cap(struct file *file, void *fh,
 759                                struct v4l2_fmtdesc *f)
 760{
 761        struct video_device *vdev = video_devdata(file);
 762        struct atomisp_device *isp = video_get_drvdata(vdev);
 763        struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
 764        struct v4l2_subdev_mbus_code_enum code = { 0 };
 765        unsigned int i, fi = 0;
 766        int rval;
 767
 768        rt_mutex_lock(&isp->mutex);
 769        rval = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, pad,
 770                                enum_mbus_code, NULL, &code);
 771        if (rval == -ENOIOCTLCMD) {
 772                dev_warn(isp->dev,
 773                         "enum_mbus_code pad op not supported. Please fix your sensor driver!\n");
 774                //      rval = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
 775                //                              video, enum_mbus_fmt, 0, &code.code);
 776        }
 777        rt_mutex_unlock(&isp->mutex);
 778
 779        if (rval)
 780                return rval;
 781
 782        for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
 783                const struct atomisp_format_bridge *format =
 784                            &atomisp_output_fmts[i];
 785
 786                /*
 787                 * Is the atomisp-supported format is valid for the
 788                 * sensor (configuration)? If not, skip it.
 789                 */
 790                if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW
 791                    && format->mbus_code != code.code)
 792                        continue;
 793
 794                /* Found a match. Now let's pick f->index'th one. */
 795                if (fi < f->index) {
 796                        fi++;
 797                        continue;
 798                }
 799
 800                strscpy(f->description, format->description,
 801                        sizeof(f->description));
 802                f->pixelformat = format->pixelformat;
 803                return 0;
 804        }
 805
 806        return -EINVAL;
 807}
 808
 809static int atomisp_g_fmt_cap(struct file *file, void *fh,
 810                             struct v4l2_format *f)
 811{
 812        struct video_device *vdev = video_devdata(file);
 813        struct atomisp_device *isp = video_get_drvdata(vdev);
 814
 815        int ret;
 816
 817        rt_mutex_lock(&isp->mutex);
 818        ret = atomisp_get_fmt(vdev, f);
 819        rt_mutex_unlock(&isp->mutex);
 820        return ret;
 821}
 822
 823static int atomisp_g_fmt_file(struct file *file, void *fh,
 824                              struct v4l2_format *f)
 825{
 826        struct video_device *vdev = video_devdata(file);
 827        struct atomisp_device *isp = video_get_drvdata(vdev);
 828        struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
 829
 830        rt_mutex_lock(&isp->mutex);
 831        f->fmt.pix = pipe->pix;
 832        rt_mutex_unlock(&isp->mutex);
 833
 834        return 0;
 835}
 836
 837/* This function looks up the closest available resolution. */
 838static int atomisp_try_fmt_cap(struct file *file, void *fh,
 839                               struct v4l2_format *f)
 840{
 841        struct video_device *vdev = video_devdata(file);
 842        struct atomisp_device *isp = video_get_drvdata(vdev);
 843        int ret;
 844
 845        rt_mutex_lock(&isp->mutex);
 846        ret = atomisp_try_fmt(vdev, &f->fmt.pix, NULL);
 847        rt_mutex_unlock(&isp->mutex);
 848        return ret;
 849}
 850
 851static int atomisp_s_fmt_cap(struct file *file, void *fh,
 852                             struct v4l2_format *f)
 853{
 854        struct video_device *vdev = video_devdata(file);
 855        struct atomisp_device *isp = video_get_drvdata(vdev);
 856        int ret;
 857
 858        rt_mutex_lock(&isp->mutex);
 859        if (isp->isp_fatal_error) {
 860                ret = -EIO;
 861                rt_mutex_unlock(&isp->mutex);
 862                return ret;
 863        }
 864        ret = atomisp_set_fmt(vdev, f);
 865        rt_mutex_unlock(&isp->mutex);
 866        return ret;
 867}
 868
 869static int atomisp_s_fmt_file(struct file *file, void *fh,
 870                              struct v4l2_format *f)
 871{
 872        struct video_device *vdev = video_devdata(file);
 873        struct atomisp_device *isp = video_get_drvdata(vdev);
 874        int ret;
 875
 876        rt_mutex_lock(&isp->mutex);
 877        ret = atomisp_set_fmt_file(vdev, f);
 878        rt_mutex_unlock(&isp->mutex);
 879        return ret;
 880}
 881
 882/*
 883 * Free videobuffer buffer priv data
 884 */
 885void atomisp_videobuf_free_buf(struct videobuf_buffer *vb)
 886{
 887        struct videobuf_vmalloc_memory *vm_mem;
 888
 889        if (!vb)
 890                return;
 891
 892        vm_mem = vb->priv;
 893        if (vm_mem && vm_mem->vaddr) {
 894                ia_css_frame_free(vm_mem->vaddr);
 895                vm_mem->vaddr = NULL;
 896        }
 897}
 898
 899/*
 900 * this function is used to free video buffer queue
 901 */
 902static void atomisp_videobuf_free_queue(struct videobuf_queue *q)
 903{
 904        int i;
 905
 906        for (i = 0; i < VIDEO_MAX_FRAME; i++) {
 907                atomisp_videobuf_free_buf(q->bufs[i]);
 908                kfree(q->bufs[i]);
 909                q->bufs[i] = NULL;
 910        }
 911}
 912
 913int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd,
 914                                uint16_t stream_id)
 915{
 916        struct atomisp_device *isp = asd->isp;
 917        struct atomisp_s3a_buf *s3a_buf = NULL, *_s3a_buf;
 918        struct atomisp_dis_buf *dis_buf = NULL, *_dis_buf;
 919        struct atomisp_metadata_buf *md_buf = NULL, *_md_buf;
 920        int count;
 921        struct ia_css_dvs_grid_info *dvs_grid_info =
 922            atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
 923        unsigned int i;
 924
 925        if (list_empty(&asd->s3a_stats) &&
 926            asd->params.curr_grid_info.s3a_grid.enable) {
 927                count = ATOMISP_CSS_Q_DEPTH +
 928                        ATOMISP_S3A_BUF_QUEUE_DEPTH_FOR_HAL;
 929                dev_dbg(isp->dev, "allocating %d 3a buffers\n", count);
 930                while (count--) {
 931                        s3a_buf = kzalloc(sizeof(struct atomisp_s3a_buf), GFP_KERNEL);
 932                        if (!s3a_buf)
 933                                goto error;
 934
 935                        if (atomisp_css_allocate_stat_buffers(
 936                                asd, stream_id, s3a_buf, NULL, NULL)) {
 937                                kfree(s3a_buf);
 938                                goto error;
 939                        }
 940
 941                        list_add_tail(&s3a_buf->list, &asd->s3a_stats);
 942                }
 943        }
 944
 945        if (list_empty(&asd->dis_stats) && dvs_grid_info &&
 946            dvs_grid_info->enable) {
 947                count = ATOMISP_CSS_Q_DEPTH + 1;
 948                dev_dbg(isp->dev, "allocating %d dis buffers\n", count);
 949                while (count--) {
 950                        dis_buf = kzalloc(sizeof(struct atomisp_dis_buf), GFP_KERNEL);
 951                        if (!dis_buf)
 952                                goto error;
 953                        if (atomisp_css_allocate_stat_buffers(
 954                                asd, stream_id, NULL, dis_buf, NULL)) {
 955                                kfree(dis_buf);
 956                                goto error;
 957                        }
 958
 959                        list_add_tail(&dis_buf->list, &asd->dis_stats);
 960                }
 961        }
 962
 963        for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
 964                if (list_empty(&asd->metadata[i]) &&
 965                    list_empty(&asd->metadata_ready[i]) &&
 966                    list_empty(&asd->metadata_in_css[i])) {
 967                        count = ATOMISP_CSS_Q_DEPTH +
 968                                ATOMISP_METADATA_QUEUE_DEPTH_FOR_HAL;
 969                        dev_dbg(isp->dev, "allocating %d metadata buffers for type %d\n",
 970                                count, i);
 971                        while (count--) {
 972                                md_buf = kzalloc(sizeof(struct atomisp_metadata_buf),
 973                                                 GFP_KERNEL);
 974                                if (!md_buf)
 975                                        goto error;
 976
 977                                if (atomisp_css_allocate_stat_buffers(
 978                                        asd, stream_id, NULL, NULL, md_buf)) {
 979                                        kfree(md_buf);
 980                                        goto error;
 981                                }
 982                                list_add_tail(&md_buf->list, &asd->metadata[i]);
 983                        }
 984                }
 985        }
 986        return 0;
 987
 988error:
 989        dev_err(isp->dev, "failed to allocate statistics buffers\n");
 990
 991        list_for_each_entry_safe(dis_buf, _dis_buf, &asd->dis_stats, list) {
 992                atomisp_css_free_dis_buffer(dis_buf);
 993                list_del(&dis_buf->list);
 994                kfree(dis_buf);
 995        }
 996
 997        list_for_each_entry_safe(s3a_buf, _s3a_buf, &asd->s3a_stats, list) {
 998                atomisp_css_free_3a_buffer(s3a_buf);
 999                list_del(&s3a_buf->list);
1000                kfree(s3a_buf);
1001        }
1002
1003        for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
1004                list_for_each_entry_safe(md_buf, _md_buf, &asd->metadata[i],
1005                                         list) {
1006                        atomisp_css_free_metadata_buffer(md_buf);
1007                        list_del(&md_buf->list);
1008                        kfree(md_buf);
1009                }
1010        }
1011        return -ENOMEM;
1012}
1013
1014/*
1015 * Initiate Memory Mapping or User Pointer I/O
1016 */
1017int __atomisp_reqbufs(struct file *file, void *fh,
1018                      struct v4l2_requestbuffers *req)
1019{
1020        struct video_device *vdev = video_devdata(file);
1021        struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1022        struct atomisp_sub_device *asd = pipe->asd;
1023        struct ia_css_frame_info frame_info;
1024        struct ia_css_frame *frame;
1025        struct videobuf_vmalloc_memory *vm_mem;
1026        u16 source_pad = atomisp_subdev_source_pad(vdev);
1027        u16 stream_id = atomisp_source_pad_to_stream_id(asd, source_pad);
1028        int ret = 0, i = 0;
1029
1030        if (req->count == 0) {
1031                mutex_lock(&pipe->capq.vb_lock);
1032                if (!list_empty(&pipe->capq.stream))
1033                        videobuf_queue_cancel(&pipe->capq);
1034
1035                atomisp_videobuf_free_queue(&pipe->capq);
1036                mutex_unlock(&pipe->capq.vb_lock);
1037                /* clear request config id */
1038                memset(pipe->frame_request_config_id, 0,
1039                       VIDEO_MAX_FRAME * sizeof(unsigned int));
1040                memset(pipe->frame_params, 0,
1041                       VIDEO_MAX_FRAME *
1042                       sizeof(struct atomisp_css_params_with_list *));
1043                return 0;
1044        }
1045
1046        ret = videobuf_reqbufs(&pipe->capq, req);
1047        if (ret)
1048                return ret;
1049
1050        atomisp_alloc_css_stat_bufs(asd, stream_id);
1051
1052        /*
1053         * for user pointer type, buffers are not really allocated here,
1054         * buffers are setup in QBUF operation through v4l2_buffer structure
1055         */
1056        if (req->memory == V4L2_MEMORY_USERPTR)
1057                return 0;
1058
1059        ret = atomisp_get_css_frame_info(asd, source_pad, &frame_info);
1060        if (ret)
1061                return ret;
1062
1063        /*
1064         * Allocate the real frame here for selected node using our
1065         * memory management function
1066         */
1067        for (i = 0; i < req->count; i++) {
1068                if (ia_css_frame_allocate_from_info(&frame, &frame_info))
1069                        goto error;
1070                vm_mem = pipe->capq.bufs[i]->priv;
1071                vm_mem->vaddr = frame;
1072        }
1073
1074        return ret;
1075
1076error:
1077        while (i--) {
1078                vm_mem = pipe->capq.bufs[i]->priv;
1079                ia_css_frame_free(vm_mem->vaddr);
1080        }
1081
1082        if (asd->vf_frame)
1083                ia_css_frame_free(asd->vf_frame);
1084
1085        return -ENOMEM;
1086}
1087
1088int atomisp_reqbufs(struct file *file, void *fh,
1089                    struct v4l2_requestbuffers *req)
1090{
1091        struct video_device *vdev = video_devdata(file);
1092        struct atomisp_device *isp = video_get_drvdata(vdev);
1093        int ret;
1094
1095        rt_mutex_lock(&isp->mutex);
1096        ret = __atomisp_reqbufs(file, fh, req);
1097        rt_mutex_unlock(&isp->mutex);
1098
1099        return ret;
1100}
1101
1102static int atomisp_reqbufs_file(struct file *file, void *fh,
1103                                struct v4l2_requestbuffers *req)
1104{
1105        struct video_device *vdev = video_devdata(file);
1106        struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1107
1108        if (req->count == 0) {
1109                mutex_lock(&pipe->outq.vb_lock);
1110                atomisp_videobuf_free_queue(&pipe->outq);
1111                mutex_unlock(&pipe->outq.vb_lock);
1112                return 0;
1113        }
1114
1115        return videobuf_reqbufs(&pipe->outq, req);
1116}
1117
1118/* application query the status of a buffer */
1119static int atomisp_querybuf(struct file *file, void *fh,
1120                            struct v4l2_buffer *buf)
1121{
1122        struct video_device *vdev = video_devdata(file);
1123        struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1124
1125        return videobuf_querybuf(&pipe->capq, buf);
1126}
1127
1128static int atomisp_querybuf_file(struct file *file, void *fh,
1129                                 struct v4l2_buffer *buf)
1130{
1131        struct video_device *vdev = video_devdata(file);
1132        struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1133
1134        return videobuf_querybuf(&pipe->outq, buf);
1135}
1136
1137/*
1138 * Applications call the VIDIOC_QBUF ioctl to enqueue an empty (capturing) or
1139 * filled (output) buffer in the drivers incoming queue.
1140 */
1141static int atomisp_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1142{
1143        static const int NOFLUSH_FLAGS = V4L2_BUF_FLAG_NO_CACHE_INVALIDATE |
1144                                         V4L2_BUF_FLAG_NO_CACHE_CLEAN;
1145        struct video_device *vdev = video_devdata(file);
1146        struct atomisp_device *isp = video_get_drvdata(vdev);
1147        struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1148        struct atomisp_sub_device *asd = pipe->asd;
1149        struct videobuf_buffer *vb;
1150        struct videobuf_vmalloc_memory *vm_mem;
1151        struct ia_css_frame_info frame_info;
1152        struct ia_css_frame *handle = NULL;
1153        u32 length;
1154        u32 pgnr;
1155        int ret = 0;
1156
1157        rt_mutex_lock(&isp->mutex);
1158        if (isp->isp_fatal_error) {
1159                ret = -EIO;
1160                goto error;
1161        }
1162
1163        if (asd->streaming == ATOMISP_DEVICE_STREAMING_STOPPING) {
1164                dev_err(isp->dev, "%s: reject, as ISP at stopping.\n",
1165                        __func__);
1166                ret = -EIO;
1167                goto error;
1168        }
1169
1170        if (!buf || buf->index >= VIDEO_MAX_FRAME ||
1171            !pipe->capq.bufs[buf->index]) {
1172                dev_err(isp->dev, "Invalid index for qbuf.\n");
1173                ret = -EINVAL;
1174                goto error;
1175        }
1176
1177        /*
1178         * For userptr type frame, we convert user space address to physic
1179         * address and reprograme out page table properly
1180         */
1181        if (buf->memory == V4L2_MEMORY_USERPTR) {
1182                vb = pipe->capq.bufs[buf->index];
1183                vm_mem = vb->priv;
1184                if (!vm_mem) {
1185                        ret = -EINVAL;
1186                        goto error;
1187                }
1188
1189                length = vb->bsize;
1190                pgnr = (length + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
1191
1192                if (vb->baddr == buf->m.userptr && vm_mem->vaddr)
1193                        goto done;
1194
1195                if (atomisp_get_css_frame_info(asd,
1196                                               atomisp_subdev_source_pad(vdev), &frame_info)) {
1197                        ret = -EIO;
1198                        goto error;
1199                }
1200
1201                ret = ia_css_frame_map(&handle, &frame_info,
1202                                            (void __user *)buf->m.userptr,
1203                                            0, pgnr);
1204                if (ret) {
1205                        dev_err(isp->dev, "Failed to map user buffer\n");
1206                        goto error;
1207                }
1208
1209                if (vm_mem->vaddr) {
1210                        mutex_lock(&pipe->capq.vb_lock);
1211                        ia_css_frame_free(vm_mem->vaddr);
1212                        vm_mem->vaddr = NULL;
1213                        vb->state = VIDEOBUF_NEEDS_INIT;
1214                        mutex_unlock(&pipe->capq.vb_lock);
1215                }
1216
1217                vm_mem->vaddr = handle;
1218
1219                buf->flags &= ~V4L2_BUF_FLAG_MAPPED;
1220                buf->flags |= V4L2_BUF_FLAG_QUEUED;
1221                buf->flags &= ~V4L2_BUF_FLAG_DONE;
1222        } else if (buf->memory == V4L2_MEMORY_MMAP) {
1223                buf->flags |= V4L2_BUF_FLAG_MAPPED;
1224                buf->flags |= V4L2_BUF_FLAG_QUEUED;
1225                buf->flags &= ~V4L2_BUF_FLAG_DONE;
1226
1227                /*
1228                 * For mmap, frames were allocated at request buffers
1229                 */
1230        }
1231
1232done:
1233        if (!((buf->flags & NOFLUSH_FLAGS) == NOFLUSH_FLAGS))
1234                wbinvd();
1235
1236        if (!atomisp_is_vf_pipe(pipe) &&
1237            (buf->reserved2 & ATOMISP_BUFFER_HAS_PER_FRAME_SETTING)) {
1238                /* this buffer will have a per-frame parameter */
1239                pipe->frame_request_config_id[buf->index] = buf->reserved2 &
1240                        ~ATOMISP_BUFFER_HAS_PER_FRAME_SETTING;
1241                dev_dbg(isp->dev,
1242                        "This buffer requires per_frame setting which has isp_config_id %d\n",
1243                        pipe->frame_request_config_id[buf->index]);
1244        } else {
1245                pipe->frame_request_config_id[buf->index] = 0;
1246        }
1247
1248        pipe->frame_params[buf->index] = NULL;
1249
1250        rt_mutex_unlock(&isp->mutex);
1251
1252        ret = videobuf_qbuf(&pipe->capq, buf);
1253        rt_mutex_lock(&isp->mutex);
1254        if (ret)
1255                goto error;
1256
1257        /* TODO: do this better, not best way to queue to css */
1258        if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) {
1259                if (!list_empty(&pipe->buffers_waiting_for_param)) {
1260                        atomisp_handle_parameter_and_buffer(pipe);
1261                } else {
1262                        atomisp_qbuffers_to_css(asd);
1263
1264                        if (!IS_ISP2401) {
1265                                if (!atomisp_is_wdt_running(asd) && atomisp_buffers_queued(asd))
1266                                        atomisp_wdt_start(asd);
1267                        } else {
1268                                if (!atomisp_is_wdt_running(pipe) &&
1269                                    atomisp_buffers_queued_pipe(pipe))
1270                                        atomisp_wdt_start_pipe(pipe);
1271                        }
1272                }
1273        }
1274
1275        /*
1276         * Workaround: Due to the design of HALv3,
1277         * sometimes in ZSL or SDV mode HAL needs to
1278         * capture multiple images within one streaming cycle.
1279         * But the capture number cannot be determined by HAL.
1280         * So HAL only sets the capture number to be 1 and queue multiple
1281         * buffers. Atomisp driver needs to check this case and re-trigger
1282         * CSS to do capture when new buffer is queued.
1283         */
1284        if (asd->continuous_mode->val &&
1285            atomisp_subdev_source_pad(vdev)
1286            == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE &&
1287            pipe->capq.streaming &&
1288            !asd->enable_raw_buffer_lock->val &&
1289            asd->params.offline_parm.num_captures == 1) {
1290                if (!IS_ISP2401) {
1291                        asd->pending_capture_request++;
1292                        dev_dbg(isp->dev, "Add one pending capture request.\n");
1293                } else {
1294                        if (asd->re_trigger_capture) {
1295                                ret = atomisp_css_offline_capture_configure(asd,
1296                                        asd->params.offline_parm.num_captures,
1297                                        asd->params.offline_parm.skip_frames,
1298                                        asd->params.offline_parm.offset);
1299                                asd->re_trigger_capture = false;
1300                                dev_dbg(isp->dev, "%s Trigger capture again ret=%d\n",
1301                                        __func__, ret);
1302
1303                        } else {
1304                                asd->pending_capture_request++;
1305                                asd->re_trigger_capture = false;
1306                                dev_dbg(isp->dev, "Add one pending capture request.\n");
1307                        }
1308                }
1309        }
1310        rt_mutex_unlock(&isp->mutex);
1311
1312        dev_dbg(isp->dev, "qbuf buffer %d (%s) for asd%d\n", buf->index,
1313                vdev->name, asd->index);
1314
1315        return ret;
1316
1317error:
1318        rt_mutex_unlock(&isp->mutex);
1319        return ret;
1320}
1321
1322static int atomisp_qbuf_file(struct file *file, void *fh,
1323                             struct v4l2_buffer *buf)
1324{
1325        struct video_device *vdev = video_devdata(file);
1326        struct atomisp_device *isp = video_get_drvdata(vdev);
1327        struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1328        int ret;
1329
1330        rt_mutex_lock(&isp->mutex);
1331        if (isp->isp_fatal_error) {
1332                ret = -EIO;
1333                goto error;
1334        }
1335
1336        if (!buf || buf->index >= VIDEO_MAX_FRAME ||
1337            !pipe->outq.bufs[buf->index]) {
1338                dev_err(isp->dev, "Invalid index for qbuf.\n");
1339                ret = -EINVAL;
1340                goto error;
1341        }
1342
1343        if (buf->memory != V4L2_MEMORY_MMAP) {
1344                dev_err(isp->dev, "Unsupported memory method\n");
1345                ret = -EINVAL;
1346                goto error;
1347        }
1348
1349        if (buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1350                dev_err(isp->dev, "Unsupported buffer type\n");
1351                ret = -EINVAL;
1352                goto error;
1353        }
1354        rt_mutex_unlock(&isp->mutex);
1355
1356        return videobuf_qbuf(&pipe->outq, buf);
1357
1358error:
1359        rt_mutex_unlock(&isp->mutex);
1360
1361        return ret;
1362}
1363
1364static int __get_frame_exp_id(struct atomisp_video_pipe *pipe,
1365                              struct v4l2_buffer *buf)
1366{
1367        struct videobuf_vmalloc_memory *vm_mem;
1368        struct ia_css_frame *handle;
1369        int i;
1370
1371        for (i = 0; pipe->capq.bufs[i]; i++) {
1372                vm_mem = pipe->capq.bufs[i]->priv;
1373                handle = vm_mem->vaddr;
1374                if (buf->index == pipe->capq.bufs[i]->i && handle)
1375                        return handle->exp_id;
1376        }
1377        return -EINVAL;
1378}
1379
1380/*
1381 * Applications call the VIDIOC_DQBUF ioctl to dequeue a filled (capturing) or
1382 * displayed (output buffer)from the driver's outgoing queue
1383 */
1384static int atomisp_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1385{
1386        struct video_device *vdev = video_devdata(file);
1387        struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1388        struct atomisp_sub_device *asd = pipe->asd;
1389        struct atomisp_device *isp = video_get_drvdata(vdev);
1390        int ret = 0;
1391
1392        rt_mutex_lock(&isp->mutex);
1393
1394        if (isp->isp_fatal_error) {
1395                rt_mutex_unlock(&isp->mutex);
1396                return -EIO;
1397        }
1398
1399        if (asd->streaming == ATOMISP_DEVICE_STREAMING_STOPPING) {
1400                rt_mutex_unlock(&isp->mutex);
1401                dev_err(isp->dev, "%s: reject, as ISP at stopping.\n",
1402                        __func__);
1403                return -EIO;
1404        }
1405
1406        rt_mutex_unlock(&isp->mutex);
1407
1408        ret = videobuf_dqbuf(&pipe->capq, buf, file->f_flags & O_NONBLOCK);
1409        if (ret) {
1410                if (ret != -EAGAIN)
1411                        dev_dbg(isp->dev, "<%s: %d\n", __func__, ret);
1412                return ret;
1413        }
1414        rt_mutex_lock(&isp->mutex);
1415        buf->bytesused = pipe->pix.sizeimage;
1416        buf->reserved = asd->frame_status[buf->index];
1417
1418        /*
1419         * Hack:
1420         * Currently frame_status in the enum type which takes no more lower
1421         * 8 bit.
1422         * use bit[31:16] for exp_id as it is only in the range of 1~255
1423         */
1424        buf->reserved &= 0x0000ffff;
1425        if (!(buf->flags & V4L2_BUF_FLAG_ERROR))
1426                buf->reserved |= __get_frame_exp_id(pipe, buf) << 16;
1427        buf->reserved2 = pipe->frame_config_id[buf->index];
1428        rt_mutex_unlock(&isp->mutex);
1429
1430        dev_dbg(isp->dev,
1431                "dqbuf buffer %d (%s) for asd%d with exp_id %d, isp_config_id %d\n",
1432                buf->index, vdev->name, asd->index, buf->reserved >> 16,
1433                buf->reserved2);
1434        return 0;
1435}
1436
1437enum ia_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device *asd)
1438{
1439        if (ATOMISP_USE_YUVPP(asd))
1440                return IA_CSS_PIPE_ID_YUVPP;
1441
1442        if (asd->continuous_mode->val) {
1443                if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)
1444                        return IA_CSS_PIPE_ID_VIDEO;
1445                else
1446                        return IA_CSS_PIPE_ID_PREVIEW;
1447        }
1448
1449        /*
1450         * Disable vf_pp and run CSS in video mode. This allows using ISP
1451         * scaling but it has one frame delay due to CSS internal buffering.
1452         */
1453        if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER)
1454                return IA_CSS_PIPE_ID_VIDEO;
1455
1456        /*
1457         * Disable vf_pp and run CSS in still capture mode. In this mode
1458         * CSS does not cause extra latency with buffering, but scaling
1459         * is not available.
1460         */
1461        if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT)
1462                return IA_CSS_PIPE_ID_CAPTURE;
1463
1464        switch (asd->run_mode->val) {
1465        case ATOMISP_RUN_MODE_PREVIEW:
1466                return IA_CSS_PIPE_ID_PREVIEW;
1467        case ATOMISP_RUN_MODE_VIDEO:
1468                return IA_CSS_PIPE_ID_VIDEO;
1469        case ATOMISP_RUN_MODE_STILL_CAPTURE:
1470        default:
1471                return IA_CSS_PIPE_ID_CAPTURE;
1472        }
1473}
1474
1475static unsigned int atomisp_sensor_start_stream(struct atomisp_sub_device *asd)
1476{
1477        struct atomisp_device *isp = asd->isp;
1478
1479        if (isp->inputs[asd->input_curr].camera_caps->
1480            sensor[asd->sensor_curr].stream_num > 1) {
1481                if (asd->high_speed_mode)
1482                        return 1;
1483                else
1484                        return 2;
1485        }
1486
1487        if (asd->vfpp->val != ATOMISP_VFPP_ENABLE ||
1488            asd->copy_mode)
1489                return 1;
1490
1491        if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO ||
1492            (asd->run_mode->val == ATOMISP_RUN_MODE_STILL_CAPTURE &&
1493             !atomisp_is_mbuscode_raw(
1494                 asd->fmt[
1495                  asd->capture_pad].fmt.code) &&
1496             !asd->continuous_mode->val))
1497                return 2;
1498        else
1499                return 1;
1500}
1501
1502int atomisp_stream_on_master_slave_sensor(struct atomisp_device *isp,
1503        bool isp_timeout)
1504{
1505        unsigned int master = -1, slave = -1, delay_slave = 0;
1506        int i, ret;
1507
1508        /*
1509         * ISP only support 2 streams now so ignore multiple master/slave
1510         * case to reduce the delay between 2 stream_on calls.
1511         */
1512        for (i = 0; i < isp->num_of_streams; i++) {
1513                int sensor_index = isp->asd[i].input_curr;
1514
1515                if (isp->inputs[sensor_index].camera_caps->
1516                    sensor[isp->asd[i].sensor_curr].is_slave)
1517                        slave = sensor_index;
1518                else
1519                        master = sensor_index;
1520        }
1521
1522        if (master == -1 || slave == -1) {
1523                master = ATOMISP_DEPTH_DEFAULT_MASTER_SENSOR;
1524                slave = ATOMISP_DEPTH_DEFAULT_SLAVE_SENSOR;
1525                dev_warn(isp->dev,
1526                         "depth mode use default master=%s.slave=%s.\n",
1527                         isp->inputs[master].camera->name,
1528                         isp->inputs[slave].camera->name);
1529        }
1530
1531        ret = v4l2_subdev_call(isp->inputs[master].camera, core,
1532                               ioctl, ATOMISP_IOC_G_DEPTH_SYNC_COMP,
1533                               &delay_slave);
1534        if (ret)
1535                dev_warn(isp->dev,
1536                         "get depth sensor %s compensation delay failed.\n",
1537                         isp->inputs[master].camera->name);
1538
1539        ret = v4l2_subdev_call(isp->inputs[master].camera,
1540                               video, s_stream, 1);
1541        if (ret) {
1542                dev_err(isp->dev, "depth mode master sensor %s stream-on failed.\n",
1543                        isp->inputs[master].camera->name);
1544                return -EINVAL;
1545        }
1546
1547        if (delay_slave != 0)
1548                udelay(delay_slave);
1549
1550        ret = v4l2_subdev_call(isp->inputs[slave].camera,
1551                               video, s_stream, 1);
1552        if (ret) {
1553                dev_err(isp->dev, "depth mode slave sensor %s stream-on failed.\n",
1554                        isp->inputs[slave].camera->name);
1555                v4l2_subdev_call(isp->inputs[master].camera, video, s_stream, 0);
1556
1557                return -EINVAL;
1558        }
1559
1560        return 0;
1561}
1562
1563/* FIXME! ISP2400 */
1564static void __wdt_on_master_slave_sensor(struct atomisp_device *isp,
1565                                         unsigned int wdt_duration)
1566{
1567        if (atomisp_buffers_queued(&isp->asd[0]))
1568                atomisp_wdt_refresh(&isp->asd[0], wdt_duration);
1569        if (atomisp_buffers_queued(&isp->asd[1]))
1570                atomisp_wdt_refresh(&isp->asd[1], wdt_duration);
1571}
1572
1573/* FIXME! ISP2401 */
1574static void __wdt_on_master_slave_sensor_pipe(struct atomisp_video_pipe *pipe,
1575                                              unsigned int wdt_duration,
1576                                              bool enable)
1577{
1578        static struct atomisp_video_pipe *pipe0;
1579
1580        if (enable) {
1581                if (atomisp_buffers_queued_pipe(pipe0))
1582                        atomisp_wdt_refresh_pipe(pipe0, wdt_duration);
1583                if (atomisp_buffers_queued_pipe(pipe))
1584                        atomisp_wdt_refresh_pipe(pipe, wdt_duration);
1585        } else {
1586                pipe0 = pipe;
1587        }
1588}
1589
1590static void atomisp_pause_buffer_event(struct atomisp_device *isp)
1591{
1592        struct v4l2_event event = {0};
1593        int i;
1594
1595        event.type = V4L2_EVENT_ATOMISP_PAUSE_BUFFER;
1596
1597        for (i = 0; i < isp->num_of_streams; i++) {
1598                int sensor_index = isp->asd[i].input_curr;
1599
1600                if (isp->inputs[sensor_index].camera_caps->
1601                    sensor[isp->asd[i].sensor_curr].is_slave) {
1602                        v4l2_event_queue(isp->asd[i].subdev.devnode, &event);
1603                        break;
1604                }
1605        }
1606}
1607
1608/* Input system HW workaround */
1609/* Input system address translation corrupts burst during */
1610/* invalidate. SW workaround for this is to set burst length */
1611/* manually to 128 in case of 13MPx snapshot and to 1 otherwise. */
1612static void atomisp_dma_burst_len_cfg(struct atomisp_sub_device *asd)
1613{
1614        struct v4l2_mbus_framefmt *sink;
1615
1616        sink = atomisp_subdev_get_ffmt(&asd->subdev, NULL,
1617                                       V4L2_SUBDEV_FORMAT_ACTIVE,
1618                                       ATOMISP_SUBDEV_PAD_SINK);
1619
1620        if (sink->width * sink->height >= 4096 * 3072)
1621                atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x7F);
1622        else
1623                atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x00);
1624}
1625
1626/*
1627 * This ioctl start the capture during streaming I/O.
1628 */
1629static int atomisp_streamon(struct file *file, void *fh,
1630                            enum v4l2_buf_type type)
1631{
1632        struct video_device *vdev = video_devdata(file);
1633        struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1634        struct atomisp_sub_device *asd = pipe->asd;
1635        struct atomisp_device *isp = video_get_drvdata(vdev);
1636        struct pci_dev *pdev = to_pci_dev(isp->dev);
1637        enum ia_css_pipe_id css_pipe_id;
1638        unsigned int sensor_start_stream;
1639        unsigned int wdt_duration = ATOMISP_ISP_TIMEOUT_DURATION;
1640        int ret = 0;
1641        unsigned long irqflags;
1642
1643        dev_dbg(isp->dev, "Start stream on pad %d for asd%d\n",
1644                atomisp_subdev_source_pad(vdev), asd->index);
1645
1646        if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1647                dev_dbg(isp->dev, "unsupported v4l2 buf type\n");
1648                return -EINVAL;
1649        }
1650
1651        rt_mutex_lock(&isp->mutex);
1652        if (isp->isp_fatal_error) {
1653                ret = -EIO;
1654                goto out;
1655        }
1656
1657        if (asd->streaming == ATOMISP_DEVICE_STREAMING_STOPPING) {
1658                ret = -EBUSY;
1659                goto out;
1660        }
1661
1662        if (pipe->capq.streaming)
1663                goto out;
1664
1665        /* Input system HW workaround */
1666        atomisp_dma_burst_len_cfg(asd);
1667
1668        /*
1669         * The number of streaming video nodes is based on which
1670         * binary is going to be run.
1671         */
1672        sensor_start_stream = atomisp_sensor_start_stream(asd);
1673
1674        spin_lock_irqsave(&pipe->irq_lock, irqflags);
1675        if (list_empty(&pipe->capq.stream)) {
1676                spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
1677                dev_dbg(isp->dev, "no buffer in the queue\n");
1678                ret = -EINVAL;
1679                goto out;
1680        }
1681        spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
1682
1683        ret = videobuf_streamon(&pipe->capq);
1684        if (ret)
1685                goto out;
1686
1687        /* Reset pending capture request count. */
1688        asd->pending_capture_request = 0;
1689        if (IS_ISP2401)
1690                asd->re_trigger_capture = false;
1691
1692        if ((atomisp_subdev_streaming_count(asd) > sensor_start_stream) &&
1693            (!isp->inputs[asd->input_curr].camera_caps->multi_stream_ctrl)) {
1694                /* trigger still capture */
1695                if (asd->continuous_mode->val &&
1696                    atomisp_subdev_source_pad(vdev)
1697                    == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) {
1698                        if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)
1699                                dev_dbg(isp->dev, "SDV last video raw buffer id: %u\n",
1700                                        asd->latest_preview_exp_id);
1701                        else
1702                                dev_dbg(isp->dev, "ZSL last preview raw buffer id: %u\n",
1703                                        asd->latest_preview_exp_id);
1704
1705                        if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) {
1706                                flush_work(&asd->delayed_init_work);
1707                                rt_mutex_unlock(&isp->mutex);
1708                                if (wait_for_completion_interruptible(
1709                                        &asd->init_done) != 0)
1710                                        return -ERESTARTSYS;
1711                                rt_mutex_lock(&isp->mutex);
1712                        }
1713
1714                        /* handle per_frame_setting parameter and buffers */
1715                        atomisp_handle_parameter_and_buffer(pipe);
1716
1717                        /*
1718                         * only ZSL/SDV capture request will be here, raise
1719                         * the ISP freq to the highest possible to minimize
1720                         * the S2S latency.
1721                         */
1722                        atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_MAX, false);
1723                        /*
1724                         * When asd->enable_raw_buffer_lock->val is true,
1725                         * An extra IOCTL is needed to call
1726                         * atomisp_css_exp_id_capture and trigger real capture
1727                         */
1728                        if (!asd->enable_raw_buffer_lock->val) {
1729                                ret = atomisp_css_offline_capture_configure(asd,
1730                                        asd->params.offline_parm.num_captures,
1731                                        asd->params.offline_parm.skip_frames,
1732                                        asd->params.offline_parm.offset);
1733                                if (ret) {
1734                                        ret = -EINVAL;
1735                                        goto out;
1736                                }
1737                                if (asd->depth_mode->val)
1738                                        atomisp_pause_buffer_event(isp);
1739                        }
1740                }
1741                atomisp_qbuffers_to_css(asd);
1742                goto out;
1743        }
1744
1745        if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) {
1746                atomisp_qbuffers_to_css(asd);
1747                goto start_sensor;
1748        }
1749
1750        css_pipe_id = atomisp_get_css_pipe_id(asd);
1751
1752        ret = atomisp_acc_load_extensions(asd);
1753        if (ret < 0) {
1754                dev_err(isp->dev, "acc extension failed to load\n");
1755                goto out;
1756        }
1757
1758        if (asd->params.css_update_params_needed) {
1759                atomisp_apply_css_parameters(asd, &asd->params.css_param);
1760                if (asd->params.css_param.update_flag.dz_config)
1761                        asd->params.config.dz_config = &asd->params.css_param.dz_config;
1762                atomisp_css_update_isp_params(asd);
1763                asd->params.css_update_params_needed = false;
1764                memset(&asd->params.css_param.update_flag, 0,
1765                       sizeof(struct atomisp_parameters));
1766        }
1767        asd->params.dvs_6axis = NULL;
1768
1769        ret = atomisp_css_start(asd, css_pipe_id, false);
1770        if (ret)
1771                goto out;
1772
1773        asd->streaming = ATOMISP_DEVICE_STREAMING_ENABLED;
1774        atomic_set(&asd->sof_count, -1);
1775        atomic_set(&asd->sequence, -1);
1776        atomic_set(&asd->sequence_temp, -1);
1777        if (isp->sw_contex.file_input)
1778                wdt_duration = ATOMISP_ISP_FILE_TIMEOUT_DURATION;
1779
1780        asd->params.dis_proj_data_valid = false;
1781        asd->latest_preview_exp_id = 0;
1782        asd->postview_exp_id = 1;
1783        asd->preview_exp_id = 1;
1784
1785        /* handle per_frame_setting parameter and buffers */
1786        atomisp_handle_parameter_and_buffer(pipe);
1787
1788        atomisp_qbuffers_to_css(asd);
1789
1790        /* Only start sensor when the last streaming instance started */
1791        if (atomisp_subdev_streaming_count(asd) < sensor_start_stream)
1792                goto out;
1793
1794start_sensor:
1795        if (isp->flash) {
1796                asd->params.num_flash_frames = 0;
1797                asd->params.flash_state = ATOMISP_FLASH_IDLE;
1798                atomisp_setup_flash(asd);
1799        }
1800
1801        if (!isp->sw_contex.file_input) {
1802                atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF,
1803                                       atomisp_css_valid_sof(isp));
1804                atomisp_csi2_configure(asd);
1805                /*
1806                 * set freq to max when streaming count > 1 which indicate
1807                 * dual camera would run
1808                 */
1809                if (atomisp_streaming_count(isp) > 1) {
1810                        if (atomisp_freq_scaling(isp,
1811                                                 ATOMISP_DFS_MODE_MAX, false) < 0)
1812                                dev_dbg(isp->dev, "DFS max mode failed!\n");
1813                } else {
1814                        if (atomisp_freq_scaling(isp,
1815                                                 ATOMISP_DFS_MODE_AUTO, false) < 0)
1816                                dev_dbg(isp->dev, "DFS auto mode failed!\n");
1817                }
1818        } else {
1819                if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_MAX, false) < 0)
1820                        dev_dbg(isp->dev, "DFS max mode failed!\n");
1821        }
1822
1823        if (asd->depth_mode->val && atomisp_streaming_count(isp) ==
1824            ATOMISP_DEPTH_SENSOR_STREAMON_COUNT) {
1825                ret = atomisp_stream_on_master_slave_sensor(isp, false);
1826                if (ret) {
1827                        dev_err(isp->dev, "master slave sensor stream on failed!\n");
1828                        goto out;
1829                }
1830                if (!IS_ISP2401)
1831                        __wdt_on_master_slave_sensor(isp, wdt_duration);
1832                else
1833                        __wdt_on_master_slave_sensor_pipe(pipe, wdt_duration, true);
1834                goto start_delay_wq;
1835        } else if (asd->depth_mode->val && (atomisp_streaming_count(isp) <
1836                                            ATOMISP_DEPTH_SENSOR_STREAMON_COUNT)) {
1837                if (IS_ISP2401)
1838                        __wdt_on_master_slave_sensor_pipe(pipe, wdt_duration, false);
1839                goto start_delay_wq;
1840        }
1841
1842        /* Enable the CSI interface on ANN B0/K0 */
1843        if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
1844                                            ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) {
1845                pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL,
1846                                      isp->saved_regs.csi_control | MRFLD_PCI_CSI_CONTROL_CSI_READY);
1847        }
1848
1849        /* stream on the sensor */
1850        ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
1851                               video, s_stream, 1);
1852        if (ret) {
1853                asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
1854                ret = -EINVAL;
1855                goto out;
1856        }
1857
1858        if (!IS_ISP2401) {
1859                if (atomisp_buffers_queued(asd))
1860                        atomisp_wdt_refresh(asd, wdt_duration);
1861        } else {
1862                if (atomisp_buffers_queued_pipe(pipe))
1863                        atomisp_wdt_refresh_pipe(pipe, wdt_duration);
1864        }
1865
1866start_delay_wq:
1867        if (asd->continuous_mode->val) {
1868                struct v4l2_mbus_framefmt *sink;
1869
1870                sink = atomisp_subdev_get_ffmt(&asd->subdev, NULL,
1871                                               V4L2_SUBDEV_FORMAT_ACTIVE,
1872                                               ATOMISP_SUBDEV_PAD_SINK);
1873
1874                reinit_completion(&asd->init_done);
1875                asd->delayed_init = ATOMISP_DELAYED_INIT_QUEUED;
1876                queue_work(asd->delayed_init_workq, &asd->delayed_init_work);
1877                atomisp_css_set_cont_prev_start_time(isp,
1878                                                     ATOMISP_CALC_CSS_PREV_OVERLAP(sink->height));
1879        } else {
1880                asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
1881        }
1882out:
1883        rt_mutex_unlock(&isp->mutex);
1884        return ret;
1885}
1886
1887int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1888{
1889        struct video_device *vdev = video_devdata(file);
1890        struct atomisp_device *isp = video_get_drvdata(vdev);
1891        struct pci_dev *pdev = to_pci_dev(isp->dev);
1892        struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1893        struct atomisp_sub_device *asd = pipe->asd;
1894        struct atomisp_video_pipe *capture_pipe = NULL;
1895        struct atomisp_video_pipe *vf_pipe = NULL;
1896        struct atomisp_video_pipe *preview_pipe = NULL;
1897        struct atomisp_video_pipe *video_pipe = NULL;
1898        struct videobuf_buffer *vb, *_vb;
1899        enum ia_css_pipe_id css_pipe_id;
1900        int ret;
1901        unsigned long flags;
1902        bool first_streamoff = false;
1903
1904        dev_dbg(isp->dev, "Stop stream on pad %d for asd%d\n",
1905                atomisp_subdev_source_pad(vdev), asd->index);
1906
1907        lockdep_assert_held(&isp->mutex);
1908        lockdep_assert_held(&isp->streamoff_mutex);
1909
1910        if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1911                dev_dbg(isp->dev, "unsupported v4l2 buf type\n");
1912                return -EINVAL;
1913        }
1914
1915        /*
1916         * do only videobuf_streamoff for capture & vf pipes in
1917         * case of continuous capture
1918         */
1919        if ((asd->continuous_mode->val ||
1920             isp->inputs[asd->input_curr].camera_caps->multi_stream_ctrl) &&
1921            atomisp_subdev_source_pad(vdev) !=
1922            ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
1923            atomisp_subdev_source_pad(vdev) !=
1924            ATOMISP_SUBDEV_PAD_SOURCE_VIDEO) {
1925                if (isp->inputs[asd->input_curr].camera_caps->multi_stream_ctrl) {
1926                        v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
1927                                         video, s_stream, 0);
1928                } else if (atomisp_subdev_source_pad(vdev)
1929                           == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) {
1930                        /* stop continuous still capture if needed */
1931                        if (asd->params.offline_parm.num_captures == -1)
1932                                atomisp_css_offline_capture_configure(asd,
1933                                                                      0, 0, 0);
1934                        atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_AUTO, false);
1935                }
1936                /*
1937                 * Currently there is no way to flush buffers queued to css.
1938                 * When doing videobuf_streamoff, active buffers will be
1939                 * marked as VIDEOBUF_NEEDS_INIT. HAL will be able to use
1940                 * these buffers again, and these buffers might be queued to
1941                 * css more than once! Warn here, if HAL has not dequeued all
1942                 * buffers back before calling streamoff.
1943                 */
1944                if (pipe->buffers_in_css != 0) {
1945                        WARN(1, "%s: buffers of vdev %s still in CSS!\n",
1946                             __func__, pipe->vdev.name);
1947
1948                        /*
1949                         * Buffers remained in css maybe dequeued out in the
1950                         * next stream on, while this will causes serious
1951                         * issues as buffers already get invalid after
1952                         * previous stream off.
1953                         *
1954                         * No way to flush buffers but to reset the whole css
1955                         */
1956                        dev_warn(isp->dev, "Reset CSS to clean up css buffers.\n");
1957                        atomisp_css_flush(isp);
1958                }
1959
1960                return videobuf_streamoff(&pipe->capq);
1961        }
1962
1963        if (!pipe->capq.streaming)
1964                return 0;
1965
1966        spin_lock_irqsave(&isp->lock, flags);
1967        if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) {
1968                asd->streaming = ATOMISP_DEVICE_STREAMING_STOPPING;
1969                first_streamoff = true;
1970        }
1971        spin_unlock_irqrestore(&isp->lock, flags);
1972
1973        if (first_streamoff) {
1974                /* if other streams are running, should not disable watch dog */
1975                rt_mutex_unlock(&isp->mutex);
1976                atomisp_wdt_stop(asd, true);
1977
1978                /*
1979                 * must stop sending pixels into GP_FIFO before stop
1980                 * the pipeline.
1981                 */
1982                if (isp->sw_contex.file_input)
1983                        v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
1984                                         video, s_stream, 0);
1985
1986                rt_mutex_lock(&isp->mutex);
1987                atomisp_acc_unload_extensions(asd);
1988        }
1989
1990        spin_lock_irqsave(&isp->lock, flags);
1991        if (atomisp_subdev_streaming_count(asd) == 1)
1992                asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
1993        spin_unlock_irqrestore(&isp->lock, flags);
1994
1995        if (!first_streamoff) {
1996                ret = videobuf_streamoff(&pipe->capq);
1997                if (ret)
1998                        return ret;
1999                goto stopsensor;
2000        }
2001
2002        atomisp_clear_css_buffer_counters(asd);
2003
2004        if (!isp->sw_contex.file_input)
2005                atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF,
2006                                       false);
2007
2008        if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) {
2009                cancel_work_sync(&asd->delayed_init_work);
2010                asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
2011        }
2012        if (first_streamoff) {
2013                css_pipe_id = atomisp_get_css_pipe_id(asd);
2014                atomisp_css_stop(asd, css_pipe_id, false);
2015        }
2016        /* cancel work queue*/
2017        if (asd->video_out_capture.users) {
2018                capture_pipe = &asd->video_out_capture;
2019                wake_up_interruptible(&capture_pipe->capq.wait);
2020        }
2021        if (asd->video_out_vf.users) {
2022                vf_pipe = &asd->video_out_vf;
2023                wake_up_interruptible(&vf_pipe->capq.wait);
2024        }
2025        if (asd->video_out_preview.users) {
2026                preview_pipe = &asd->video_out_preview;
2027                wake_up_interruptible(&preview_pipe->capq.wait);
2028        }
2029        if (asd->video_out_video_capture.users) {
2030                video_pipe = &asd->video_out_video_capture;
2031                wake_up_interruptible(&video_pipe->capq.wait);
2032        }
2033        ret = videobuf_streamoff(&pipe->capq);
2034        if (ret)
2035                return ret;
2036
2037        /* cleanup css here */
2038        /* no need for this, as ISP will be reset anyway */
2039        /*atomisp_flush_bufs_in_css(isp);*/
2040
2041        spin_lock_irqsave(&pipe->irq_lock, flags);
2042        list_for_each_entry_safe(vb, _vb, &pipe->activeq, queue) {
2043                vb->state = VIDEOBUF_PREPARED;
2044                list_del(&vb->queue);
2045        }
2046        list_for_each_entry_safe(vb, _vb, &pipe->buffers_waiting_for_param, queue) {
2047                vb->state = VIDEOBUF_PREPARED;
2048                list_del(&vb->queue);
2049                pipe->frame_request_config_id[vb->i] = 0;
2050        }
2051        spin_unlock_irqrestore(&pipe->irq_lock, flags);
2052
2053        atomisp_subdev_cleanup_pending_events(asd);
2054stopsensor:
2055        if (atomisp_subdev_streaming_count(asd) + 1
2056            != atomisp_sensor_start_stream(asd))
2057                return 0;
2058
2059        if (!isp->sw_contex.file_input)
2060                ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2061                                       video, s_stream, 0);
2062
2063        if (isp->flash) {
2064                asd->params.num_flash_frames = 0;
2065                asd->params.flash_state = ATOMISP_FLASH_IDLE;
2066        }
2067
2068        /* if other streams are running, isp should not be powered off */
2069        if (atomisp_streaming_count(isp)) {
2070                atomisp_css_flush(isp);
2071                return 0;
2072        }
2073
2074        /* Disable the CSI interface on ANN B0/K0 */
2075        if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
2076                                            ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) {
2077                pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL,
2078                                      isp->saved_regs.csi_control & ~MRFLD_PCI_CSI_CONTROL_CSI_READY);
2079        }
2080
2081        if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false))
2082                dev_warn(isp->dev, "DFS failed.\n");
2083        /*
2084         * ISP work around, need to reset isp
2085         * Is it correct time to reset ISP when first node does streamoff?
2086         */
2087        if (isp->sw_contex.power_state == ATOM_ISP_POWER_UP) {
2088                unsigned int i;
2089                bool recreate_streams[MAX_STREAM_NUM] = {0};
2090
2091                if (isp->isp_timeout)
2092                        dev_err(isp->dev, "%s: Resetting with WA activated",
2093                                __func__);
2094                /*
2095                 * It is possible that the other asd stream is in the stage
2096                 * that v4l2_setfmt is just get called on it, which will
2097                 * create css stream on that stream. But at this point, there
2098                 * is no way to destroy the css stream created on that stream.
2099                 *
2100                 * So force stream destroy here.
2101                 */
2102                for (i = 0; i < isp->num_of_streams; i++) {
2103                        if (isp->asd[i].stream_prepared) {
2104                                atomisp_destroy_pipes_stream_force(&isp->
2105                                                                   asd[i]);
2106                                recreate_streams[i] = true;
2107                        }
2108                }
2109
2110                /* disable  PUNIT/ISP acknowlede/handshake - SRSE=3 */
2111                pci_write_config_dword(pdev, PCI_I_CONTROL,
2112                                       isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK);
2113                dev_err(isp->dev, "atomisp_reset");
2114                atomisp_reset(isp);
2115                for (i = 0; i < isp->num_of_streams; i++) {
2116                        if (recreate_streams[i])
2117                                atomisp_create_pipes_stream(&isp->asd[i]);
2118                }
2119                isp->isp_timeout = false;
2120        }
2121        return ret;
2122}
2123
2124static int atomisp_streamoff(struct file *file, void *fh,
2125                             enum v4l2_buf_type type)
2126{
2127        struct video_device *vdev = video_devdata(file);
2128        struct atomisp_device *isp = video_get_drvdata(vdev);
2129        int rval;
2130
2131        mutex_lock(&isp->streamoff_mutex);
2132        rt_mutex_lock(&isp->mutex);
2133        rval = __atomisp_streamoff(file, fh, type);
2134        rt_mutex_unlock(&isp->mutex);
2135        mutex_unlock(&isp->streamoff_mutex);
2136
2137        return rval;
2138}
2139
2140/*
2141 * To get the current value of a control.
2142 * applications initialize the id field of a struct v4l2_control and
2143 * call this ioctl with a pointer to this structure
2144 */
2145static int atomisp_g_ctrl(struct file *file, void *fh,
2146                          struct v4l2_control *control)
2147{
2148        struct video_device *vdev = video_devdata(file);
2149        struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2150        struct atomisp_device *isp = video_get_drvdata(vdev);
2151        int i, ret = -EINVAL;
2152
2153        for (i = 0; i < ctrls_num; i++) {
2154                if (ci_v4l2_controls[i].id == control->id) {
2155                        ret = 0;
2156                        break;
2157                }
2158        }
2159
2160        if (ret)
2161                return ret;
2162
2163        rt_mutex_lock(&isp->mutex);
2164
2165        switch (control->id) {
2166        case V4L2_CID_IRIS_ABSOLUTE:
2167        case V4L2_CID_EXPOSURE_ABSOLUTE:
2168        case V4L2_CID_FNUMBER_ABSOLUTE:
2169        case V4L2_CID_2A_STATUS:
2170        case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
2171        case V4L2_CID_EXPOSURE:
2172        case V4L2_CID_EXPOSURE_AUTO:
2173        case V4L2_CID_SCENE_MODE:
2174        case V4L2_CID_ISO_SENSITIVITY:
2175        case V4L2_CID_ISO_SENSITIVITY_AUTO:
2176        case V4L2_CID_CONTRAST:
2177        case V4L2_CID_SATURATION:
2178        case V4L2_CID_SHARPNESS:
2179        case V4L2_CID_3A_LOCK:
2180        case V4L2_CID_EXPOSURE_ZONE_NUM:
2181        case V4L2_CID_TEST_PATTERN:
2182        case V4L2_CID_TEST_PATTERN_COLOR_R:
2183        case V4L2_CID_TEST_PATTERN_COLOR_GR:
2184        case V4L2_CID_TEST_PATTERN_COLOR_GB:
2185        case V4L2_CID_TEST_PATTERN_COLOR_B:
2186                rt_mutex_unlock(&isp->mutex);
2187                return v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->
2188                                   ctrl_handler, control);
2189        case V4L2_CID_COLORFX:
2190                ret = atomisp_color_effect(asd, 0, &control->value);
2191                break;
2192        case V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION:
2193                ret = atomisp_bad_pixel(asd, 0, &control->value);
2194                break;
2195        case V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC:
2196                ret = atomisp_gdc_cac(asd, 0, &control->value);
2197                break;
2198        case V4L2_CID_ATOMISP_VIDEO_STABLIZATION:
2199                ret = atomisp_video_stable(asd, 0, &control->value);
2200                break;
2201        case V4L2_CID_ATOMISP_FIXED_PATTERN_NR:
2202                ret = atomisp_fixed_pattern(asd, 0, &control->value);
2203                break;
2204        case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION:
2205                ret = atomisp_false_color(asd, 0, &control->value);
2206                break;
2207        case V4L2_CID_ATOMISP_LOW_LIGHT:
2208                ret = atomisp_low_light(asd, 0, &control->value);
2209                break;
2210        default:
2211                ret = -EINVAL;
2212                break;
2213        }
2214
2215        rt_mutex_unlock(&isp->mutex);
2216        return ret;
2217}
2218
2219/*
2220 * To change the value of a control.
2221 * applications initialize the id and value fields of a struct v4l2_control
2222 * and call this ioctl.
2223 */
2224static int atomisp_s_ctrl(struct file *file, void *fh,
2225                          struct v4l2_control *control)
2226{
2227        struct video_device *vdev = video_devdata(file);
2228        struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2229        struct atomisp_device *isp = video_get_drvdata(vdev);
2230        int i, ret = -EINVAL;
2231
2232        for (i = 0; i < ctrls_num; i++) {
2233                if (ci_v4l2_controls[i].id == control->id) {
2234                        ret = 0;
2235                        break;
2236                }
2237        }
2238
2239        if (ret)
2240                return ret;
2241
2242        rt_mutex_lock(&isp->mutex);
2243        switch (control->id) {
2244        case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
2245        case V4L2_CID_EXPOSURE:
2246        case V4L2_CID_EXPOSURE_AUTO:
2247        case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
2248        case V4L2_CID_SCENE_MODE:
2249        case V4L2_CID_ISO_SENSITIVITY:
2250        case V4L2_CID_ISO_SENSITIVITY_AUTO:
2251        case V4L2_CID_POWER_LINE_FREQUENCY:
2252        case V4L2_CID_EXPOSURE_METERING:
2253        case V4L2_CID_CONTRAST:
2254        case V4L2_CID_SATURATION:
2255        case V4L2_CID_SHARPNESS:
2256        case V4L2_CID_3A_LOCK:
2257        case V4L2_CID_COLORFX_CBCR:
2258        case V4L2_CID_TEST_PATTERN:
2259        case V4L2_CID_TEST_PATTERN_COLOR_R:
2260        case V4L2_CID_TEST_PATTERN_COLOR_GR:
2261        case V4L2_CID_TEST_PATTERN_COLOR_GB:
2262        case V4L2_CID_TEST_PATTERN_COLOR_B:
2263                rt_mutex_unlock(&isp->mutex);
2264                return v4l2_s_ctrl(NULL,
2265                                   isp->inputs[asd->input_curr].camera->
2266                                   ctrl_handler, control);
2267        case V4L2_CID_COLORFX:
2268                ret = atomisp_color_effect(asd, 1, &control->value);
2269                break;
2270        case V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION:
2271                ret = atomisp_bad_pixel(asd, 1, &control->value);
2272                break;
2273        case V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC:
2274                ret = atomisp_gdc_cac(asd, 1, &control->value);
2275                break;
2276        case V4L2_CID_ATOMISP_VIDEO_STABLIZATION:
2277                ret = atomisp_video_stable(asd, 1, &control->value);
2278                break;
2279        case V4L2_CID_ATOMISP_FIXED_PATTERN_NR:
2280                ret = atomisp_fixed_pattern(asd, 1, &control->value);
2281                break;
2282        case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION:
2283                ret = atomisp_false_color(asd, 1, &control->value);
2284                break;
2285        case V4L2_CID_REQUEST_FLASH:
2286                ret = atomisp_flash_enable(asd, control->value);
2287                break;
2288        case V4L2_CID_ATOMISP_LOW_LIGHT:
2289                ret = atomisp_low_light(asd, 1, &control->value);
2290                break;
2291        default:
2292                ret = -EINVAL;
2293                break;
2294        }
2295        rt_mutex_unlock(&isp->mutex);
2296        return ret;
2297}
2298
2299/*
2300 * To query the attributes of a control.
2301 * applications set the id field of a struct v4l2_queryctrl and call the
2302 * this ioctl with a pointer to this structure. The driver fills
2303 * the rest of the structure.
2304 */
2305static int atomisp_queryctl(struct file *file, void *fh,
2306                            struct v4l2_queryctrl *qc)
2307{
2308        int i, ret = -EINVAL;
2309        struct video_device *vdev = video_devdata(file);
2310        struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2311        struct atomisp_device *isp = video_get_drvdata(vdev);
2312
2313        switch (qc->id) {
2314        case V4L2_CID_FOCUS_ABSOLUTE:
2315        case V4L2_CID_FOCUS_RELATIVE:
2316        case V4L2_CID_FOCUS_STATUS:
2317                if (!IS_ISP2401) {
2318                        return v4l2_queryctrl(isp->inputs[asd->input_curr].camera->
2319                                            ctrl_handler, qc);
2320                }
2321                /* ISP2401 */
2322                if (isp->motor)
2323                        return v4l2_queryctrl(isp->motor->ctrl_handler, qc);
2324                else
2325                        return v4l2_queryctrl(isp->inputs[asd->input_curr].
2326                                              camera->ctrl_handler, qc);
2327        }
2328
2329        if (qc->id & V4L2_CTRL_FLAG_NEXT_CTRL)
2330                return ret;
2331
2332        for (i = 0; i < ctrls_num; i++) {
2333                if (ci_v4l2_controls[i].id == qc->id) {
2334                        memcpy(qc, &ci_v4l2_controls[i],
2335                               sizeof(struct v4l2_queryctrl));
2336                        qc->reserved[0] = 0;
2337                        ret = 0;
2338                        break;
2339                }
2340        }
2341        if (ret != 0)
2342                qc->flags = V4L2_CTRL_FLAG_DISABLED;
2343
2344        return ret;
2345}
2346
2347static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh,
2348                                      struct v4l2_ext_controls *c)
2349{
2350        struct video_device *vdev = video_devdata(file);
2351        struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2352        struct atomisp_device *isp = video_get_drvdata(vdev);
2353        struct v4l2_subdev *motor;
2354        struct v4l2_control ctrl;
2355        int i;
2356        int ret = 0;
2357
2358        if (!IS_ISP2401)
2359                motor = isp->inputs[asd->input_curr].motor;
2360        else
2361                motor = isp->motor;
2362
2363        for (i = 0; i < c->count; i++) {
2364                ctrl.id = c->controls[i].id;
2365                ctrl.value = c->controls[i].value;
2366                switch (ctrl.id) {
2367                case V4L2_CID_EXPOSURE_ABSOLUTE:
2368                case V4L2_CID_EXPOSURE_AUTO:
2369                case V4L2_CID_IRIS_ABSOLUTE:
2370                case V4L2_CID_FNUMBER_ABSOLUTE:
2371                case V4L2_CID_BIN_FACTOR_HORZ:
2372                case V4L2_CID_BIN_FACTOR_VERT:
2373                case V4L2_CID_3A_LOCK:
2374                case V4L2_CID_TEST_PATTERN:
2375                case V4L2_CID_TEST_PATTERN_COLOR_R:
2376                case V4L2_CID_TEST_PATTERN_COLOR_GR:
2377                case V4L2_CID_TEST_PATTERN_COLOR_GB:
2378                case V4L2_CID_TEST_PATTERN_COLOR_B:
2379                        /*
2380                         * Exposure related control will be handled by sensor
2381                         * driver
2382                         */
2383                        ret =
2384                            v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->
2385                                        ctrl_handler, &ctrl);
2386                        break;
2387                case V4L2_CID_FOCUS_ABSOLUTE:
2388                case V4L2_CID_FOCUS_RELATIVE:
2389                case V4L2_CID_FOCUS_STATUS:
2390                case V4L2_CID_FOCUS_AUTO:
2391                        if (motor)
2392                                ret = v4l2_g_ctrl(motor->ctrl_handler, &ctrl);
2393                        break;
2394                case V4L2_CID_FLASH_STATUS:
2395                case V4L2_CID_FLASH_INTENSITY:
2396                case V4L2_CID_FLASH_TORCH_INTENSITY:
2397                case V4L2_CID_FLASH_INDICATOR_INTENSITY:
2398                case V4L2_CID_FLASH_TIMEOUT:
2399                case V4L2_CID_FLASH_STROBE:
2400                case V4L2_CID_FLASH_MODE:
2401                case V4L2_CID_FLASH_STATUS_REGISTER:
2402                        if (isp->flash)
2403                                ret =
2404                                    v4l2_g_ctrl(isp->flash->ctrl_handler,
2405                                                &ctrl);
2406                        break;
2407                case V4L2_CID_ZOOM_ABSOLUTE:
2408                        rt_mutex_lock(&isp->mutex);
2409                        ret = atomisp_digital_zoom(asd, 0, &ctrl.value);
2410                        rt_mutex_unlock(&isp->mutex);
2411                        break;
2412                case V4L2_CID_G_SKIP_FRAMES:
2413                        ret = v4l2_subdev_call(
2414                                  isp->inputs[asd->input_curr].camera,
2415                                  sensor, g_skip_frames, (u32 *)&ctrl.value);
2416                        break;
2417                default:
2418                        ret = -EINVAL;
2419                }
2420
2421                if (ret) {
2422                        c->error_idx = i;
2423                        break;
2424                }
2425                c->controls[i].value = ctrl.value;
2426        }
2427        return ret;
2428}
2429
2430/* This ioctl allows the application to get multiple controls by class */
2431static int atomisp_g_ext_ctrls(struct file *file, void *fh,
2432                               struct v4l2_ext_controls *c)
2433{
2434        struct v4l2_control ctrl;
2435        int i, ret = 0;
2436
2437        /*
2438         * input_lock is not need for the Camera related IOCTLs
2439         * The input_lock downgrade the FPS of 3A
2440         */
2441        ret = atomisp_camera_g_ext_ctrls(file, fh, c);
2442        if (ret != -EINVAL)
2443                return ret;
2444
2445        for (i = 0; i < c->count; i++) {
2446                ctrl.id = c->controls[i].id;
2447                ctrl.value = c->controls[i].value;
2448                ret = atomisp_g_ctrl(file, fh, &ctrl);
2449                c->controls[i].value = ctrl.value;
2450                if (ret) {
2451                        c->error_idx = i;
2452                        break;
2453                }
2454        }
2455        return ret;
2456}
2457
2458static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh,
2459                                      struct v4l2_ext_controls *c)
2460{
2461        struct video_device *vdev = video_devdata(file);
2462        struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2463        struct atomisp_device *isp = video_get_drvdata(vdev);
2464        struct v4l2_subdev *motor;
2465        struct v4l2_control ctrl;
2466        int i;
2467        int ret = 0;
2468
2469        if (!IS_ISP2401)
2470                motor = isp->inputs[asd->input_curr].motor;
2471        else
2472                motor = isp->motor;
2473
2474        for (i = 0; i < c->count; i++) {
2475                struct v4l2_ctrl *ctr;
2476
2477                ctrl.id = c->controls[i].id;
2478                ctrl.value = c->controls[i].value;
2479                switch (ctrl.id) {
2480                case V4L2_CID_EXPOSURE_ABSOLUTE:
2481                case V4L2_CID_EXPOSURE_AUTO:
2482                case V4L2_CID_EXPOSURE_METERING:
2483                case V4L2_CID_IRIS_ABSOLUTE:
2484                case V4L2_CID_FNUMBER_ABSOLUTE:
2485                case V4L2_CID_VCM_TIMING:
2486                case V4L2_CID_VCM_SLEW:
2487                case V4L2_CID_3A_LOCK:
2488                case V4L2_CID_TEST_PATTERN:
2489                case V4L2_CID_TEST_PATTERN_COLOR_R:
2490                case V4L2_CID_TEST_PATTERN_COLOR_GR:
2491                case V4L2_CID_TEST_PATTERN_COLOR_GB:
2492                case V4L2_CID_TEST_PATTERN_COLOR_B:
2493                        ret = v4l2_s_ctrl(NULL,
2494                                          isp->inputs[asd->input_curr].camera->
2495                                          ctrl_handler, &ctrl);
2496                        break;
2497                case V4L2_CID_FOCUS_ABSOLUTE:
2498                case V4L2_CID_FOCUS_RELATIVE:
2499                case V4L2_CID_FOCUS_STATUS:
2500                case V4L2_CID_FOCUS_AUTO:
2501                        if (motor)
2502                                ret = v4l2_s_ctrl(NULL, motor->ctrl_handler,
2503                                                  &ctrl);
2504                        else
2505                                ret = v4l2_s_ctrl(NULL,
2506                                                  isp->inputs[asd->input_curr].
2507                                                  camera->ctrl_handler, &ctrl);
2508                        break;
2509                case V4L2_CID_FLASH_STATUS:
2510                case V4L2_CID_FLASH_INTENSITY:
2511                case V4L2_CID_FLASH_TORCH_INTENSITY:
2512                case V4L2_CID_FLASH_INDICATOR_INTENSITY:
2513                case V4L2_CID_FLASH_TIMEOUT:
2514                case V4L2_CID_FLASH_STROBE:
2515                case V4L2_CID_FLASH_MODE:
2516                case V4L2_CID_FLASH_STATUS_REGISTER:
2517                        rt_mutex_lock(&isp->mutex);
2518                        if (isp->flash) {
2519                                ret =
2520                                    v4l2_s_ctrl(NULL, isp->flash->ctrl_handler,
2521                                                &ctrl);
2522                                /*
2523                                 * When flash mode is changed we need to reset
2524                                 * flash state
2525                                 */
2526                                if (ctrl.id == V4L2_CID_FLASH_MODE) {
2527                                        asd->params.flash_state =
2528                                            ATOMISP_FLASH_IDLE;
2529                                        asd->params.num_flash_frames = 0;
2530                                }
2531                        }
2532                        rt_mutex_unlock(&isp->mutex);
2533                        break;
2534                case V4L2_CID_ZOOM_ABSOLUTE:
2535                        rt_mutex_lock(&isp->mutex);
2536                        ret = atomisp_digital_zoom(asd, 1, &ctrl.value);
2537                        rt_mutex_unlock(&isp->mutex);
2538                        break;
2539                default:
2540                        ctr = v4l2_ctrl_find(&asd->ctrl_handler, ctrl.id);
2541                        if (ctr)
2542                                ret = v4l2_ctrl_s_ctrl(ctr, ctrl.value);
2543                        else
2544                                ret = -EINVAL;
2545                }
2546
2547                if (ret) {
2548                        c->error_idx = i;
2549                        break;
2550                }
2551                c->controls[i].value = ctrl.value;
2552        }
2553        return ret;
2554}
2555
2556/* This ioctl allows the application to set multiple controls by class */
2557static int atomisp_s_ext_ctrls(struct file *file, void *fh,
2558                               struct v4l2_ext_controls *c)
2559{
2560        struct v4l2_control ctrl;
2561        int i, ret = 0;
2562
2563        /*
2564         * input_lock is not need for the Camera related IOCTLs
2565         * The input_lock downgrade the FPS of 3A
2566         */
2567        ret = atomisp_camera_s_ext_ctrls(file, fh, c);
2568        if (ret != -EINVAL)
2569                return ret;
2570
2571        for (i = 0; i < c->count; i++) {
2572                ctrl.id = c->controls[i].id;
2573                ctrl.value = c->controls[i].value;
2574                ret = atomisp_s_ctrl(file, fh, &ctrl);
2575                c->controls[i].value = ctrl.value;
2576                if (ret) {
2577                        c->error_idx = i;
2578                        break;
2579                }
2580        }
2581        return ret;
2582}
2583
2584/*
2585 * vidioc_g/s_param are used to switch isp running mode
2586 */
2587static int atomisp_g_parm(struct file *file, void *fh,
2588                          struct v4l2_streamparm *parm)
2589{
2590        struct video_device *vdev = video_devdata(file);
2591        struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2592        struct atomisp_device *isp = video_get_drvdata(vdev);
2593
2594        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2595                dev_err(isp->dev, "unsupported v4l2 buf type\n");
2596                return -EINVAL;
2597        }
2598
2599        rt_mutex_lock(&isp->mutex);
2600        parm->parm.capture.capturemode = asd->run_mode->val;
2601        rt_mutex_unlock(&isp->mutex);
2602
2603        return 0;
2604}
2605
2606static int atomisp_s_parm(struct file *file, void *fh,
2607                          struct v4l2_streamparm *parm)
2608{
2609        struct video_device *vdev = video_devdata(file);
2610        struct atomisp_device *isp = video_get_drvdata(vdev);
2611        struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2612        int mode;
2613        int rval;
2614        int fps;
2615
2616        if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2617                dev_err(isp->dev, "unsupported v4l2 buf type\n");
2618                return -EINVAL;
2619        }
2620
2621        rt_mutex_lock(&isp->mutex);
2622
2623        asd->high_speed_mode = false;
2624        switch (parm->parm.capture.capturemode) {
2625        case CI_MODE_NONE: {
2626                struct v4l2_subdev_frame_interval fi = {0};
2627
2628                fi.interval = parm->parm.capture.timeperframe;
2629
2630                rval = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2631                                        video, s_frame_interval, &fi);
2632                if (!rval)
2633                        parm->parm.capture.timeperframe = fi.interval;
2634
2635                if (fi.interval.numerator != 0) {
2636                        fps = fi.interval.denominator / fi.interval.numerator;
2637                        if (fps > 30)
2638                                asd->high_speed_mode = true;
2639                }
2640
2641                goto out;
2642        }
2643        case CI_MODE_VIDEO:
2644                mode = ATOMISP_RUN_MODE_VIDEO;
2645                break;
2646        case CI_MODE_STILL_CAPTURE:
2647                mode = ATOMISP_RUN_MODE_STILL_CAPTURE;
2648                break;
2649        case CI_MODE_CONTINUOUS:
2650                mode = ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE;
2651                break;
2652        case CI_MODE_PREVIEW:
2653                mode = ATOMISP_RUN_MODE_PREVIEW;
2654                break;
2655        default:
2656                rval = -EINVAL;
2657                goto out;
2658        }
2659
2660        rval = v4l2_ctrl_s_ctrl(asd->run_mode, mode);
2661
2662out:
2663        rt_mutex_unlock(&isp->mutex);
2664
2665        return rval == -ENOIOCTLCMD ? 0 : rval;
2666}
2667
2668static int atomisp_s_parm_file(struct file *file, void *fh,
2669                               struct v4l2_streamparm *parm)
2670{
2671        struct video_device *vdev = video_devdata(file);
2672        struct atomisp_device *isp = video_get_drvdata(vdev);
2673
2674        if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
2675                dev_err(isp->dev, "unsupported v4l2 buf type for output\n");
2676                return -EINVAL;
2677        }
2678
2679        rt_mutex_lock(&isp->mutex);
2680        isp->sw_contex.file_input = true;
2681        rt_mutex_unlock(&isp->mutex);
2682
2683        return 0;
2684}
2685
2686static long atomisp_vidioc_default(struct file *file, void *fh,
2687                                   bool valid_prio, unsigned int cmd, void *arg)
2688{
2689        struct video_device *vdev = video_devdata(file);
2690        struct atomisp_device *isp = video_get_drvdata(vdev);
2691        struct atomisp_sub_device *asd;
2692        struct v4l2_subdev *motor;
2693        bool acc_node;
2694        int err;
2695
2696        acc_node = !strcmp(vdev->name, "ATOMISP ISP ACC");
2697        if (acc_node)
2698                asd = atomisp_to_acc_pipe(vdev)->asd;
2699        else
2700                asd = atomisp_to_video_pipe(vdev)->asd;
2701
2702        if (!IS_ISP2401)
2703                motor = isp->inputs[asd->input_curr].motor;
2704        else
2705                motor = isp->motor;
2706
2707        switch (cmd) {
2708        case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
2709        case ATOMISP_IOC_S_EXPOSURE:
2710        case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
2711        case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
2712        case ATOMISP_IOC_EXT_ISP_CTRL:
2713        case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO:
2714        case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE:
2715        case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE:
2716        case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT:
2717        case ATOMISP_IOC_S_SENSOR_EE_CONFIG:
2718        case ATOMISP_IOC_G_UPDATE_EXPOSURE:
2719                /* we do not need take isp->mutex for these IOCTLs */
2720                break;
2721        default:
2722                rt_mutex_lock(&isp->mutex);
2723                break;
2724        }
2725        switch (cmd) {
2726        case ATOMISP_IOC_S_SENSOR_RUNMODE:
2727                if (IS_ISP2401)
2728                        err = atomisp_set_sensor_runmode(asd, arg);
2729                else
2730                        err = -EINVAL;
2731                break;
2732
2733        case ATOMISP_IOC_G_XNR:
2734                err = atomisp_xnr(asd, 0, arg);
2735                break;
2736
2737        case ATOMISP_IOC_S_XNR:
2738                err = atomisp_xnr(asd, 1, arg);
2739                break;
2740
2741        case ATOMISP_IOC_G_NR:
2742                err = atomisp_nr(asd, 0, arg);
2743                break;
2744
2745        case ATOMISP_IOC_S_NR:
2746                err = atomisp_nr(asd, 1, arg);
2747                break;
2748
2749        case ATOMISP_IOC_G_TNR:
2750                err = atomisp_tnr(asd, 0, arg);
2751                break;
2752
2753        case ATOMISP_IOC_S_TNR:
2754                err = atomisp_tnr(asd, 1, arg);
2755                break;
2756
2757        case ATOMISP_IOC_G_BLACK_LEVEL_COMP:
2758                err = atomisp_black_level(asd, 0, arg);
2759                break;
2760
2761        case ATOMISP_IOC_S_BLACK_LEVEL_COMP:
2762                err = atomisp_black_level(asd, 1, arg);
2763                break;
2764
2765        case ATOMISP_IOC_G_EE:
2766                err = atomisp_ee(asd, 0, arg);
2767                break;
2768
2769        case ATOMISP_IOC_S_EE:
2770                err = atomisp_ee(asd, 1, arg);
2771                break;
2772
2773        case ATOMISP_IOC_G_DIS_STAT:
2774                err = atomisp_get_dis_stat(asd, arg);
2775                break;
2776
2777        case ATOMISP_IOC_G_DVS2_BQ_RESOLUTIONS:
2778                err = atomisp_get_dvs2_bq_resolutions(asd, arg);
2779                break;
2780
2781        case ATOMISP_IOC_S_DIS_COEFS:
2782                err = atomisp_css_cp_dvs2_coefs(asd, arg,
2783                                                &asd->params.css_param, true);
2784                if (!err && arg)
2785                        asd->params.css_update_params_needed = true;
2786                break;
2787
2788        case ATOMISP_IOC_S_DIS_VECTOR:
2789                err = atomisp_cp_dvs_6axis_config(asd, arg,
2790                                                  &asd->params.css_param, true);
2791                if (!err && arg)
2792                        asd->params.css_update_params_needed = true;
2793                break;
2794
2795        case ATOMISP_IOC_G_ISP_PARM:
2796                err = atomisp_param(asd, 0, arg);
2797                break;
2798
2799        case ATOMISP_IOC_S_ISP_PARM:
2800                err = atomisp_param(asd, 1, arg);
2801                break;
2802
2803        case ATOMISP_IOC_G_3A_STAT:
2804                err = atomisp_3a_stat(asd, 0, arg);
2805                break;
2806
2807        case ATOMISP_IOC_G_ISP_GAMMA:
2808                err = atomisp_gamma(asd, 0, arg);
2809                break;
2810
2811        case ATOMISP_IOC_S_ISP_GAMMA:
2812                err = atomisp_gamma(asd, 1, arg);
2813                break;
2814
2815        case ATOMISP_IOC_G_ISP_GDC_TAB:
2816                err = atomisp_gdc_cac_table(asd, 0, arg);
2817                break;
2818
2819        case ATOMISP_IOC_S_ISP_GDC_TAB:
2820                err = atomisp_gdc_cac_table(asd, 1, arg);
2821                break;
2822
2823        case ATOMISP_IOC_G_ISP_MACC:
2824                err = atomisp_macc_table(asd, 0, arg);
2825                break;
2826
2827        case ATOMISP_IOC_S_ISP_MACC:
2828                err = atomisp_macc_table(asd, 1, arg);
2829                break;
2830
2831        case ATOMISP_IOC_G_ISP_BAD_PIXEL_DETECTION:
2832                err = atomisp_bad_pixel_param(asd, 0, arg);
2833                break;
2834
2835        case ATOMISP_IOC_S_ISP_BAD_PIXEL_DETECTION:
2836                err = atomisp_bad_pixel_param(asd, 1, arg);
2837                break;
2838
2839        case ATOMISP_IOC_G_ISP_FALSE_COLOR_CORRECTION:
2840                err = atomisp_false_color_param(asd, 0, arg);
2841                break;
2842
2843        case ATOMISP_IOC_S_ISP_FALSE_COLOR_CORRECTION:
2844                err = atomisp_false_color_param(asd, 1, arg);
2845                break;
2846
2847        case ATOMISP_IOC_G_ISP_CTC:
2848                err = atomisp_ctc(asd, 0, arg);
2849                break;
2850
2851        case ATOMISP_IOC_S_ISP_CTC:
2852                err = atomisp_ctc(asd, 1, arg);
2853                break;
2854
2855        case ATOMISP_IOC_G_ISP_WHITE_BALANCE:
2856                err = atomisp_white_balance_param(asd, 0, arg);
2857                break;
2858
2859        case ATOMISP_IOC_S_ISP_WHITE_BALANCE:
2860                err = atomisp_white_balance_param(asd, 1, arg);
2861                break;
2862
2863        case ATOMISP_IOC_G_3A_CONFIG:
2864                err = atomisp_3a_config_param(asd, 0, arg);
2865                break;
2866
2867        case ATOMISP_IOC_S_3A_CONFIG:
2868                err = atomisp_3a_config_param(asd, 1, arg);
2869                break;
2870
2871        case ATOMISP_IOC_S_ISP_FPN_TABLE:
2872                err = atomisp_fixed_pattern_table(asd, arg);
2873                break;
2874
2875        case ATOMISP_IOC_ISP_MAKERNOTE:
2876                err = atomisp_exif_makernote(asd, arg);
2877                break;
2878
2879        case ATOMISP_IOC_G_SENSOR_MODE_DATA:
2880                err = atomisp_get_sensor_mode_data(asd, arg);
2881                break;
2882
2883        case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
2884                if (motor)
2885                        err = v4l2_subdev_call(motor, core, ioctl, cmd, arg);
2886                else
2887                        err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2888                                               core, ioctl, cmd, arg);
2889                break;
2890
2891        case ATOMISP_IOC_S_EXPOSURE:
2892        case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
2893        case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
2894        case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO:
2895        case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE:
2896        case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE:
2897        case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT:
2898                err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2899                                       core, ioctl, cmd, arg);
2900                break;
2901        case ATOMISP_IOC_G_UPDATE_EXPOSURE:
2902                if (IS_ISP2401)
2903                        err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2904                                               core, ioctl, cmd, arg);
2905                else
2906                        err = -EINVAL;
2907                break;
2908
2909        case ATOMISP_IOC_ACC_LOAD:
2910                err = atomisp_acc_load(asd, arg);
2911                break;
2912
2913        case ATOMISP_IOC_ACC_LOAD_TO_PIPE:
2914                err = atomisp_acc_load_to_pipe(asd, arg);
2915                break;
2916
2917        case ATOMISP_IOC_ACC_UNLOAD:
2918                err = atomisp_acc_unload(asd, arg);
2919                break;
2920
2921        case ATOMISP_IOC_ACC_START:
2922                err = atomisp_acc_start(asd, arg);
2923                break;
2924
2925        case ATOMISP_IOC_ACC_WAIT:
2926                err = atomisp_acc_wait(asd, arg);
2927                break;
2928
2929        case ATOMISP_IOC_ACC_MAP:
2930                err = atomisp_acc_map(asd, arg);
2931                break;
2932
2933        case ATOMISP_IOC_ACC_UNMAP:
2934                err = atomisp_acc_unmap(asd, arg);
2935                break;
2936
2937        case ATOMISP_IOC_ACC_S_MAPPED_ARG:
2938                err = atomisp_acc_s_mapped_arg(asd, arg);
2939                break;
2940
2941        case ATOMISP_IOC_S_ISP_SHD_TAB:
2942                err = atomisp_set_shading_table(asd, arg);
2943                break;
2944
2945        case ATOMISP_IOC_G_ISP_GAMMA_CORRECTION:
2946                err = atomisp_gamma_correction(asd, 0, arg);
2947                break;
2948
2949        case ATOMISP_IOC_S_ISP_GAMMA_CORRECTION:
2950                err = atomisp_gamma_correction(asd, 1, arg);
2951                break;
2952
2953        case ATOMISP_IOC_S_PARAMETERS:
2954                err = atomisp_set_parameters(vdev, arg);
2955                break;
2956
2957        case ATOMISP_IOC_S_CONT_CAPTURE_CONFIG:
2958                err = atomisp_offline_capture_configure(asd, arg);
2959                break;
2960        case ATOMISP_IOC_G_METADATA:
2961                err = atomisp_get_metadata(asd, 0, arg);
2962                break;
2963        case ATOMISP_IOC_G_METADATA_BY_TYPE:
2964                err = atomisp_get_metadata_by_type(asd, 0, arg);
2965                break;
2966        case ATOMISP_IOC_EXT_ISP_CTRL:
2967                err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2968                                       core, ioctl, cmd, arg);
2969                break;
2970        case ATOMISP_IOC_EXP_ID_UNLOCK:
2971                err = atomisp_exp_id_unlock(asd, arg);
2972                break;
2973        case ATOMISP_IOC_EXP_ID_CAPTURE:
2974                err = atomisp_exp_id_capture(asd, arg);
2975                break;
2976        case ATOMISP_IOC_S_ENABLE_DZ_CAPT_PIPE:
2977                err = atomisp_enable_dz_capt_pipe(asd, arg);
2978                break;
2979        case ATOMISP_IOC_G_FORMATS_CONFIG:
2980                err = atomisp_formats(asd, 0, arg);
2981                break;
2982
2983        case ATOMISP_IOC_S_FORMATS_CONFIG:
2984                err = atomisp_formats(asd, 1, arg);
2985                break;
2986        case ATOMISP_IOC_S_EXPOSURE_WINDOW:
2987                err = atomisp_s_ae_window(asd, arg);
2988                break;
2989        case ATOMISP_IOC_S_ACC_STATE:
2990                err = atomisp_acc_set_state(asd, arg);
2991                break;
2992        case ATOMISP_IOC_G_ACC_STATE:
2993                err = atomisp_acc_get_state(asd, arg);
2994                break;
2995        case ATOMISP_IOC_INJECT_A_FAKE_EVENT:
2996                err = atomisp_inject_a_fake_event(asd, arg);
2997                break;
2998        case ATOMISP_IOC_G_INVALID_FRAME_NUM:
2999                err = atomisp_get_invalid_frame_num(vdev, arg);
3000                break;
3001        case ATOMISP_IOC_S_ARRAY_RESOLUTION:
3002                err = atomisp_set_array_res(asd, arg);
3003                break;
3004        default:
3005                err = -EINVAL;
3006                break;
3007        }
3008
3009        switch (cmd) {
3010        case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
3011        case ATOMISP_IOC_S_EXPOSURE:
3012        case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
3013        case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
3014        case ATOMISP_IOC_EXT_ISP_CTRL:
3015        case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO:
3016        case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE:
3017        case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE:
3018        case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT:
3019        case ATOMISP_IOC_G_UPDATE_EXPOSURE:
3020                break;
3021        default:
3022                rt_mutex_unlock(&isp->mutex);
3023                break;
3024        }
3025        return err;
3026}
3027
3028const struct v4l2_ioctl_ops atomisp_ioctl_ops = {
3029        .vidioc_querycap = atomisp_querycap,
3030        .vidioc_enum_input = atomisp_enum_input,
3031        .vidioc_g_input = atomisp_g_input,
3032        .vidioc_s_input = atomisp_s_input,
3033        .vidioc_queryctrl = atomisp_queryctl,
3034        .vidioc_s_ctrl = atomisp_s_ctrl,
3035        .vidioc_g_ctrl = atomisp_g_ctrl,
3036        .vidioc_s_ext_ctrls = atomisp_s_ext_ctrls,
3037        .vidioc_g_ext_ctrls = atomisp_g_ext_ctrls,
3038        .vidioc_enum_fmt_vid_cap = atomisp_enum_fmt_cap,
3039        .vidioc_try_fmt_vid_cap = atomisp_try_fmt_cap,
3040        .vidioc_g_fmt_vid_cap = atomisp_g_fmt_cap,
3041        .vidioc_s_fmt_vid_cap = atomisp_s_fmt_cap,
3042        .vidioc_reqbufs = atomisp_reqbufs,
3043        .vidioc_querybuf = atomisp_querybuf,
3044        .vidioc_qbuf = atomisp_qbuf,
3045        .vidioc_dqbuf = atomisp_dqbuf,
3046        .vidioc_streamon = atomisp_streamon,
3047        .vidioc_streamoff = atomisp_streamoff,
3048        .vidioc_default = atomisp_vidioc_default,
3049        .vidioc_s_parm = atomisp_s_parm,
3050        .vidioc_g_parm = atomisp_g_parm,
3051};
3052
3053const struct v4l2_ioctl_ops atomisp_file_ioctl_ops = {
3054        .vidioc_querycap = atomisp_querycap,
3055        .vidioc_g_fmt_vid_out = atomisp_g_fmt_file,
3056        .vidioc_s_fmt_vid_out = atomisp_s_fmt_file,
3057        .vidioc_s_parm = atomisp_s_parm_file,
3058        .vidioc_reqbufs = atomisp_reqbufs_file,
3059        .vidioc_querybuf = atomisp_querybuf_file,
3060        .vidioc_qbuf = atomisp_qbuf_file,
3061};
3062