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