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