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