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 return isp->asd.streaming == ATOMISP_DEVICE_STREAMING_ENABLED; 630 } 631 632 /* 633 * get input are used to get current primary/secondary camera 634 */ 635 static int atomisp_g_input(struct file *file, void *fh, unsigned int *input) 636 { 637 struct video_device *vdev = video_devdata(file); 638 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 639 640 *input = asd->input_curr; 641 return 0; 642 } 643 644 static int atomisp_s_fmt_cap(struct file *file, void *fh, 645 struct v4l2_format *f) 646 { 647 struct video_device *vdev = video_devdata(file); 648 649 return atomisp_set_fmt(vdev, f); 650 } 651 652 /* 653 * set input are used to set current primary/secondary camera 654 */ 655 static int atomisp_s_input(struct file *file, void *fh, unsigned int input) 656 { 657 struct video_device *vdev = video_devdata(file); 658 struct atomisp_device *isp = video_get_drvdata(vdev); 659 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 660 struct atomisp_sub_device *asd = pipe->asd; 661 struct v4l2_subdev *camera = NULL; 662 struct v4l2_subdev *motor; 663 int ret; 664 665 ret = atomisp_pipe_check(pipe, true); 666 if (ret) 667 return ret; 668 669 if (input >= ATOM_ISP_MAX_INPUTS || input >= isp->input_cnt) { 670 dev_dbg(isp->dev, "input_cnt: %d\n", isp->input_cnt); 671 return -EINVAL; 672 } 673 674 camera = isp->inputs[input].camera; 675 if (!camera) { 676 dev_err(isp->dev, "%s, no camera\n", __func__); 677 return -EINVAL; 678 } 679 680 /* power off the current owned sensor, as it is not used this time */ 681 if (isp->inputs[asd->input_curr].asd == asd && 682 asd->input_curr != input) { 683 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 684 core, s_power, 0); 685 if (ret && ret != -ENOIOCTLCMD) 686 dev_warn(isp->dev, 687 "Failed to power-off sensor\n"); 688 /* clear the asd field to show this camera is not used */ 689 isp->inputs[asd->input_curr].asd = NULL; 690 } 691 692 /* powe on the new sensor */ 693 ret = v4l2_subdev_call(isp->inputs[input].camera, core, s_power, 1); 694 if (ret && ret != -ENOIOCTLCMD) { 695 dev_err(isp->dev, "Failed to power-on sensor\n"); 696 return ret; 697 } 698 /* 699 * Some sensor driver resets the run mode during power-on, thus force 700 * update the run mode to sensor after power-on. 701 */ 702 atomisp_update_run_mode(asd); 703 704 /* select operating sensor */ 705 ret = v4l2_subdev_call(isp->inputs[input].camera, video, s_routing, 706 0, isp->inputs[input].sensor_index, 0); 707 if (ret && (ret != -ENOIOCTLCMD)) { 708 dev_err(isp->dev, "Failed to select sensor\n"); 709 return ret; 710 } 711 712 if (!IS_ISP2401) { 713 motor = isp->inputs[input].motor; 714 } else { 715 motor = isp->motor; 716 if (motor) 717 ret = v4l2_subdev_call(motor, core, s_power, 1); 718 } 719 720 if (motor) 721 ret = v4l2_subdev_call(motor, core, init, 1); 722 723 asd->input_curr = input; 724 /* mark this camera is used by the current stream */ 725 isp->inputs[input].asd = asd; 726 727 return 0; 728 } 729 730 static int atomisp_enum_framesizes(struct file *file, void *priv, 731 struct v4l2_frmsizeenum *fsize) 732 { 733 struct video_device *vdev = video_devdata(file); 734 struct atomisp_device *isp = video_get_drvdata(vdev); 735 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 736 struct v4l2_subdev_frame_size_enum fse = { 737 .index = fsize->index, 738 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 739 }; 740 int ret; 741 742 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 743 pad, enum_frame_size, NULL, &fse); 744 if (ret) 745 return ret; 746 747 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; 748 fsize->discrete.width = fse.max_width - pad_w; 749 fsize->discrete.height = fse.max_height - pad_h; 750 751 return 0; 752 } 753 754 static int atomisp_enum_frameintervals(struct file *file, void *priv, 755 struct v4l2_frmivalenum *fival) 756 { 757 struct video_device *vdev = video_devdata(file); 758 struct atomisp_device *isp = video_get_drvdata(vdev); 759 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 760 struct v4l2_subdev_frame_interval_enum fie = { 761 .code = atomisp_in_fmt_conv[0].code, 762 .index = fival->index, 763 .width = fival->width, 764 .height = fival->height, 765 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 766 }; 767 int ret; 768 769 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 770 pad, enum_frame_interval, NULL, 771 &fie); 772 if (ret) 773 return ret; 774 775 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; 776 fival->discrete = fie.interval; 777 778 return ret; 779 } 780 781 static int atomisp_enum_fmt_cap(struct file *file, void *fh, 782 struct v4l2_fmtdesc *f) 783 { 784 struct video_device *vdev = video_devdata(file); 785 struct atomisp_device *isp = video_get_drvdata(vdev); 786 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 787 struct v4l2_subdev_mbus_code_enum code = { 788 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 789 }; 790 const struct atomisp_format_bridge *format; 791 struct v4l2_subdev *camera; 792 unsigned int i, fi = 0; 793 int rval; 794 795 camera = isp->inputs[asd->input_curr].camera; 796 if(!camera) { 797 dev_err(isp->dev, "%s(): camera is NULL, device is %s\n", 798 __func__, vdev->name); 799 return -EINVAL; 800 } 801 802 rval = v4l2_subdev_call(camera, pad, enum_mbus_code, NULL, &code); 803 if (rval == -ENOIOCTLCMD) { 804 dev_warn(isp->dev, 805 "enum_mbus_code pad op not supported by %s. Please fix your sensor driver!\n", 806 camera->name); 807 } 808 809 if (rval) 810 return rval; 811 812 for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) { 813 format = &atomisp_output_fmts[i]; 814 815 /* 816 * Is the atomisp-supported format is valid for the 817 * sensor (configuration)? If not, skip it. 818 * 819 * FIXME: fix the pipeline to allow sensor format too. 820 */ 821 if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) 822 continue; 823 824 /* Found a match. Now let's pick f->index'th one. */ 825 if (fi < f->index) { 826 fi++; 827 continue; 828 } 829 830 strscpy(f->description, format->description, 831 sizeof(f->description)); 832 f->pixelformat = format->pixelformat; 833 return 0; 834 } 835 836 return -EINVAL; 837 } 838 839 static int atomisp_adjust_fmt(struct v4l2_format *f) 840 { 841 const struct atomisp_format_bridge *format_bridge; 842 u32 padded_width; 843 844 format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat); 845 /* Currently, raw formats are broken!!! */ 846 if (!format_bridge || format_bridge->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) { 847 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; 848 849 format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat); 850 if (!format_bridge) 851 return -EINVAL; 852 } 853 854 padded_width = f->fmt.pix.width + pad_w; 855 856 if (format_bridge->planar) { 857 f->fmt.pix.bytesperline = padded_width; 858 f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * 859 DIV_ROUND_UP(format_bridge->depth * 860 padded_width, 8)); 861 } else { 862 f->fmt.pix.bytesperline = DIV_ROUND_UP(format_bridge->depth * 863 padded_width, 8); 864 f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * f->fmt.pix.bytesperline); 865 } 866 867 if (f->fmt.pix.field == V4L2_FIELD_ANY) 868 f->fmt.pix.field = V4L2_FIELD_NONE; 869 870 /* 871 * FIXME: do we need to setup this differently, depending on the 872 * sensor or the pipeline? 873 */ 874 f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; 875 f->fmt.pix.ycbcr_enc = V4L2_YCBCR_ENC_709; 876 f->fmt.pix.xfer_func = V4L2_XFER_FUNC_709; 877 878 f->fmt.pix.width -= pad_w; 879 f->fmt.pix.height -= pad_h; 880 881 return 0; 882 } 883 884 /* This function looks up the closest available resolution. */ 885 static int atomisp_try_fmt_cap(struct file *file, void *fh, 886 struct v4l2_format *f) 887 { 888 struct video_device *vdev = video_devdata(file); 889 u32 pixfmt = f->fmt.pix.pixelformat; 890 int ret; 891 892 /* 893 * atomisp_try_fmt() gived results with padding included, note 894 * (this gets removed again by the atomisp_adjust_fmt() call below. 895 */ 896 f->fmt.pix.width += pad_w; 897 f->fmt.pix.height += pad_h; 898 899 ret = atomisp_try_fmt(vdev, &f->fmt.pix, NULL); 900 if (ret) 901 return ret; 902 903 /* 904 * atomisp_try_fmt() replaces pixelformat with the sensors native 905 * format, restore the actual format requested by userspace. 906 */ 907 f->fmt.pix.pixelformat = pixfmt; 908 909 return atomisp_adjust_fmt(f); 910 } 911 912 static int atomisp_g_fmt_cap(struct file *file, void *fh, 913 struct v4l2_format *f) 914 { 915 struct video_device *vdev = video_devdata(file); 916 struct atomisp_video_pipe *pipe; 917 918 pipe = atomisp_to_video_pipe(vdev); 919 920 f->fmt.pix = pipe->pix; 921 922 /* If s_fmt was issued, just return whatever is was previouly set */ 923 if (f->fmt.pix.sizeimage) 924 return 0; 925 926 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; 927 f->fmt.pix.width = 10000; 928 f->fmt.pix.height = 10000; 929 930 return atomisp_try_fmt_cap(file, fh, f); 931 } 932 933 int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd, 934 uint16_t stream_id) 935 { 936 struct atomisp_device *isp = asd->isp; 937 struct atomisp_s3a_buf *s3a_buf = NULL, *_s3a_buf; 938 struct atomisp_dis_buf *dis_buf = NULL, *_dis_buf; 939 struct atomisp_metadata_buf *md_buf = NULL, *_md_buf; 940 int count; 941 struct ia_css_dvs_grid_info *dvs_grid_info = 942 atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info); 943 unsigned int i; 944 945 if (list_empty(&asd->s3a_stats) && 946 asd->params.curr_grid_info.s3a_grid.enable) { 947 count = ATOMISP_CSS_Q_DEPTH + 948 ATOMISP_S3A_BUF_QUEUE_DEPTH_FOR_HAL; 949 dev_dbg(isp->dev, "allocating %d 3a buffers\n", count); 950 while (count--) { 951 s3a_buf = kzalloc(sizeof(struct atomisp_s3a_buf), GFP_KERNEL); 952 if (!s3a_buf) 953 goto error; 954 955 if (atomisp_css_allocate_stat_buffers( 956 asd, stream_id, s3a_buf, NULL, NULL)) { 957 kfree(s3a_buf); 958 goto error; 959 } 960 961 list_add_tail(&s3a_buf->list, &asd->s3a_stats); 962 } 963 } 964 965 if (list_empty(&asd->dis_stats) && dvs_grid_info && 966 dvs_grid_info->enable) { 967 count = ATOMISP_CSS_Q_DEPTH + 1; 968 dev_dbg(isp->dev, "allocating %d dis buffers\n", count); 969 while (count--) { 970 dis_buf = kzalloc(sizeof(struct atomisp_dis_buf), GFP_KERNEL); 971 if (!dis_buf) 972 goto error; 973 if (atomisp_css_allocate_stat_buffers( 974 asd, stream_id, NULL, dis_buf, NULL)) { 975 kfree(dis_buf); 976 goto error; 977 } 978 979 list_add_tail(&dis_buf->list, &asd->dis_stats); 980 } 981 } 982 983 for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) { 984 if (list_empty(&asd->metadata[i]) && 985 list_empty(&asd->metadata_ready[i]) && 986 list_empty(&asd->metadata_in_css[i])) { 987 count = ATOMISP_CSS_Q_DEPTH + 988 ATOMISP_METADATA_QUEUE_DEPTH_FOR_HAL; 989 dev_dbg(isp->dev, "allocating %d metadata buffers for type %d\n", 990 count, i); 991 while (count--) { 992 md_buf = kzalloc(sizeof(struct atomisp_metadata_buf), 993 GFP_KERNEL); 994 if (!md_buf) 995 goto error; 996 997 if (atomisp_css_allocate_stat_buffers( 998 asd, stream_id, NULL, NULL, md_buf)) { 999 kfree(md_buf); 1000 goto error; 1001 } 1002 list_add_tail(&md_buf->list, &asd->metadata[i]); 1003 } 1004 } 1005 } 1006 return 0; 1007 1008 error: 1009 dev_err(isp->dev, "failed to allocate statistics buffers\n"); 1010 1011 list_for_each_entry_safe(dis_buf, _dis_buf, &asd->dis_stats, list) { 1012 atomisp_css_free_dis_buffer(dis_buf); 1013 list_del(&dis_buf->list); 1014 kfree(dis_buf); 1015 } 1016 1017 list_for_each_entry_safe(s3a_buf, _s3a_buf, &asd->s3a_stats, list) { 1018 atomisp_css_free_3a_buffer(s3a_buf); 1019 list_del(&s3a_buf->list); 1020 kfree(s3a_buf); 1021 } 1022 1023 for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) { 1024 list_for_each_entry_safe(md_buf, _md_buf, &asd->metadata[i], 1025 list) { 1026 atomisp_css_free_metadata_buffer(md_buf); 1027 list_del(&md_buf->list); 1028 kfree(md_buf); 1029 } 1030 } 1031 return -ENOMEM; 1032 } 1033 1034 /* 1035 * FIXME the abuse of buf->reserved2 in the qbuf and dqbuf wrappers comes from 1036 * the original atomisp buffer handling and should be replaced with proper V4L2 1037 * per frame parameters use. 1038 * 1039 * Once this is fixed these wrappers can be removed, replacing them with direct 1040 * calls to vb2_ioctl_[d]qbuf(). 1041 */ 1042 static int atomisp_qbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer *buf) 1043 { 1044 struct video_device *vdev = video_devdata(file); 1045 struct atomisp_device *isp = video_get_drvdata(vdev); 1046 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 1047 1048 if (buf->index >= vdev->queue->num_buffers) 1049 return -EINVAL; 1050 1051 if (!atomisp_is_vf_pipe(pipe) && 1052 (buf->reserved2 & ATOMISP_BUFFER_HAS_PER_FRAME_SETTING)) { 1053 /* this buffer will have a per-frame parameter */ 1054 pipe->frame_request_config_id[buf->index] = buf->reserved2 & 1055 ~ATOMISP_BUFFER_HAS_PER_FRAME_SETTING; 1056 dev_dbg(isp->dev, 1057 "This buffer requires per_frame setting which has isp_config_id %d\n", 1058 pipe->frame_request_config_id[buf->index]); 1059 } else { 1060 pipe->frame_request_config_id[buf->index] = 0; 1061 } 1062 1063 return vb2_ioctl_qbuf(file, fh, buf); 1064 } 1065 1066 static int atomisp_dqbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer *buf) 1067 { 1068 struct video_device *vdev = video_devdata(file); 1069 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 1070 struct atomisp_sub_device *asd = pipe->asd; 1071 struct atomisp_device *isp = video_get_drvdata(vdev); 1072 struct ia_css_frame *frame; 1073 struct vb2_buffer *vb; 1074 int ret; 1075 1076 ret = vb2_ioctl_dqbuf(file, fh, buf); 1077 if (ret) 1078 return ret; 1079 1080 vb = pipe->vb_queue.bufs[buf->index]; 1081 frame = vb_to_frame(vb); 1082 1083 buf->reserved = asd->frame_status[buf->index]; 1084 1085 /* 1086 * Hack: 1087 * Currently frame_status in the enum type which takes no more lower 1088 * 8 bit. 1089 * use bit[31:16] for exp_id as it is only in the range of 1~255 1090 */ 1091 buf->reserved &= 0x0000ffff; 1092 if (!(buf->flags & V4L2_BUF_FLAG_ERROR)) 1093 buf->reserved |= frame->exp_id; 1094 buf->reserved2 = pipe->frame_config_id[buf->index]; 1095 1096 dev_dbg(isp->dev, 1097 "dqbuf buffer %d (%s) with exp_id %d, isp_config_id %d\n", 1098 buf->index, vdev->name, buf->reserved >> 16, buf->reserved2); 1099 return 0; 1100 } 1101 1102 enum ia_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device *asd) 1103 { 1104 /* 1105 * Disable vf_pp and run CSS in video mode. This allows using ISP 1106 * scaling but it has one frame delay due to CSS internal buffering. 1107 */ 1108 if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) 1109 return IA_CSS_PIPE_ID_VIDEO; 1110 1111 /* 1112 * Disable vf_pp and run CSS in still capture mode. In this mode 1113 * CSS does not cause extra latency with buffering, but scaling 1114 * is not available. 1115 */ 1116 if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) 1117 return IA_CSS_PIPE_ID_CAPTURE; 1118 1119 switch (asd->run_mode->val) { 1120 case ATOMISP_RUN_MODE_PREVIEW: 1121 return IA_CSS_PIPE_ID_PREVIEW; 1122 case ATOMISP_RUN_MODE_VIDEO: 1123 return IA_CSS_PIPE_ID_VIDEO; 1124 case ATOMISP_RUN_MODE_STILL_CAPTURE: 1125 default: 1126 return IA_CSS_PIPE_ID_CAPTURE; 1127 } 1128 } 1129 1130 static unsigned int atomisp_sensor_start_stream(struct atomisp_sub_device *asd) 1131 { 1132 if (asd->vfpp->val != ATOMISP_VFPP_ENABLE || 1133 asd->copy_mode) 1134 return 1; 1135 1136 if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO || 1137 (asd->run_mode->val == ATOMISP_RUN_MODE_STILL_CAPTURE && 1138 !atomisp_is_mbuscode_raw(asd->fmt[asd->capture_pad].fmt.code))) 1139 return 2; 1140 else 1141 return 1; 1142 } 1143 1144 /* Input system HW workaround */ 1145 /* Input system address translation corrupts burst during */ 1146 /* invalidate. SW workaround for this is to set burst length */ 1147 /* manually to 128 in case of 13MPx snapshot and to 1 otherwise. */ 1148 static void atomisp_dma_burst_len_cfg(struct atomisp_sub_device *asd) 1149 { 1150 struct v4l2_mbus_framefmt *sink; 1151 1152 sink = atomisp_subdev_get_ffmt(&asd->subdev, NULL, 1153 V4L2_SUBDEV_FORMAT_ACTIVE, 1154 ATOMISP_SUBDEV_PAD_SINK); 1155 1156 if (sink->width * sink->height >= 4096 * 3072) 1157 atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x7F); 1158 else 1159 atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x00); 1160 } 1161 1162 int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) 1163 { 1164 struct atomisp_video_pipe *pipe = vq_to_pipe(vq); 1165 struct atomisp_sub_device *asd = pipe->asd; 1166 struct video_device *vdev = &pipe->vdev; 1167 struct atomisp_device *isp = asd->isp; 1168 struct pci_dev *pdev = to_pci_dev(isp->dev); 1169 enum ia_css_pipe_id css_pipe_id; 1170 unsigned int sensor_start_stream; 1171 unsigned long irqflags; 1172 int ret; 1173 1174 mutex_lock(&isp->mutex); 1175 1176 dev_dbg(isp->dev, "Start stream on pad %d\n", atomisp_subdev_source_pad(vdev)); 1177 1178 ret = atomisp_pipe_check(pipe, false); 1179 if (ret) 1180 goto out_unlock; 1181 1182 /* Input system HW workaround */ 1183 atomisp_dma_burst_len_cfg(asd); 1184 1185 /* 1186 * The number of streaming video nodes is based on which 1187 * binary is going to be run. 1188 */ 1189 sensor_start_stream = atomisp_sensor_start_stream(asd); 1190 1191 if (atomisp_subdev_streaming_count(asd) > sensor_start_stream) { 1192 atomisp_qbuffers_to_css(asd); 1193 ret = 0; 1194 goto out_unlock; 1195 } 1196 1197 if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) { 1198 atomisp_qbuffers_to_css(asd); 1199 goto start_sensor; 1200 } 1201 1202 css_pipe_id = atomisp_get_css_pipe_id(asd); 1203 1204 /* Invalidate caches. FIXME: should flush only necessary buffers */ 1205 wbinvd(); 1206 1207 if (asd->params.css_update_params_needed) { 1208 atomisp_apply_css_parameters(asd, &asd->params.css_param); 1209 if (asd->params.css_param.update_flag.dz_config) 1210 asd->params.config.dz_config = &asd->params.css_param.dz_config; 1211 atomisp_css_update_isp_params(asd); 1212 asd->params.css_update_params_needed = false; 1213 memset(&asd->params.css_param.update_flag, 0, 1214 sizeof(struct atomisp_parameters)); 1215 } 1216 asd->params.dvs_6axis = NULL; 1217 1218 ret = atomisp_css_start(asd, css_pipe_id, false); 1219 if (ret) { 1220 atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_QUEUED, true); 1221 goto out_unlock; 1222 } 1223 1224 spin_lock_irqsave(&isp->lock, irqflags); 1225 asd->streaming = ATOMISP_DEVICE_STREAMING_ENABLED; 1226 spin_unlock_irqrestore(&isp->lock, irqflags); 1227 atomic_set(&asd->sof_count, -1); 1228 atomic_set(&asd->sequence, -1); 1229 atomic_set(&asd->sequence_temp, -1); 1230 1231 asd->params.dis_proj_data_valid = false; 1232 asd->latest_preview_exp_id = 0; 1233 asd->postview_exp_id = 1; 1234 asd->preview_exp_id = 1; 1235 1236 /* handle per_frame_setting parameter and buffers */ 1237 atomisp_handle_parameter_and_buffer(pipe); 1238 1239 atomisp_qbuffers_to_css(asd); 1240 1241 /* Only start sensor when the last streaming instance started */ 1242 if (atomisp_subdev_streaming_count(asd) < sensor_start_stream) { 1243 ret = 0; 1244 goto out_unlock; 1245 } 1246 1247 start_sensor: 1248 if (isp->flash) { 1249 asd->params.num_flash_frames = 0; 1250 asd->params.flash_state = ATOMISP_FLASH_IDLE; 1251 atomisp_setup_flash(asd); 1252 } 1253 1254 atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, 1255 atomisp_css_valid_sof(isp)); 1256 atomisp_csi2_configure(asd); 1257 /* 1258 * set freq to max when streaming count > 1 which indicate 1259 * dual camera would run 1260 */ 1261 if (atomisp_streaming_count(isp) > 1) { 1262 if (atomisp_freq_scaling(isp, 1263 ATOMISP_DFS_MODE_MAX, false) < 0) 1264 dev_dbg(isp->dev, "DFS max mode failed!\n"); 1265 } else { 1266 if (atomisp_freq_scaling(isp, 1267 ATOMISP_DFS_MODE_AUTO, false) < 0) 1268 dev_dbg(isp->dev, "DFS auto mode failed!\n"); 1269 } 1270 1271 /* Enable the CSI interface on ANN B0/K0 */ 1272 if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << 1273 ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) { 1274 pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL, 1275 isp->saved_regs.csi_control | MRFLD_PCI_CSI_CONTROL_CSI_READY); 1276 } 1277 1278 /* stream on the sensor */ 1279 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 1280 video, s_stream, 1); 1281 if (ret) { 1282 spin_lock_irqsave(&isp->lock, irqflags); 1283 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED; 1284 spin_unlock_irqrestore(&isp->lock, irqflags); 1285 ret = -EINVAL; 1286 goto out_unlock; 1287 } 1288 1289 out_unlock: 1290 mutex_unlock(&isp->mutex); 1291 return ret; 1292 } 1293 1294 void atomisp_stop_streaming(struct vb2_queue *vq) 1295 { 1296 struct atomisp_video_pipe *pipe = vq_to_pipe(vq); 1297 struct atomisp_sub_device *asd = pipe->asd; 1298 struct video_device *vdev = &pipe->vdev; 1299 struct atomisp_device *isp = asd->isp; 1300 struct pci_dev *pdev = to_pci_dev(isp->dev); 1301 enum ia_css_pipe_id css_pipe_id; 1302 bool recreate_stream = false; 1303 bool first_streamoff = false; 1304 unsigned long flags; 1305 int ret; 1306 1307 mutex_lock(&isp->mutex); 1308 1309 dev_dbg(isp->dev, "Stop stream on pad %d\n", atomisp_subdev_source_pad(vdev)); 1310 1311 /* 1312 * There is no guarantee that the buffers queued to / owned by the ISP 1313 * will properly be returned to the queue when stopping. Set a flag to 1314 * avoid new buffers getting queued and then wait for all the current 1315 * buffers to finish. 1316 */ 1317 pipe->stopping = true; 1318 mutex_unlock(&isp->mutex); 1319 /* wait max 1 second */ 1320 ret = wait_event_timeout(pipe->vb_queue.done_wq, 1321 atomisp_buffers_in_css(pipe) == 0, HZ); 1322 mutex_lock(&isp->mutex); 1323 pipe->stopping = false; 1324 if (ret == 0) 1325 dev_warn(isp->dev, "Warning timeout waiting for CSS to return buffers\n"); 1326 1327 if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) 1328 first_streamoff = true; 1329 1330 spin_lock_irqsave(&isp->lock, flags); 1331 if (atomisp_subdev_streaming_count(asd) == 1) 1332 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED; 1333 else 1334 asd->streaming = ATOMISP_DEVICE_STREAMING_STOPPING; 1335 spin_unlock_irqrestore(&isp->lock, flags); 1336 1337 if (!first_streamoff) 1338 goto stopsensor; 1339 1340 atomisp_clear_css_buffer_counters(asd); 1341 atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false); 1342 1343 css_pipe_id = atomisp_get_css_pipe_id(asd); 1344 atomisp_css_stop(asd, css_pipe_id, false); 1345 1346 atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_ERROR, true); 1347 1348 atomisp_subdev_cleanup_pending_events(asd); 1349 stopsensor: 1350 if (atomisp_subdev_streaming_count(asd) != atomisp_sensor_start_stream(asd)) 1351 goto out_unlock; 1352 1353 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 1354 video, s_stream, 0); 1355 1356 if (isp->flash) { 1357 asd->params.num_flash_frames = 0; 1358 asd->params.flash_state = ATOMISP_FLASH_IDLE; 1359 } 1360 1361 /* if other streams are running, isp should not be powered off */ 1362 if (atomisp_streaming_count(isp)) { 1363 atomisp_css_flush(isp); 1364 goto out_unlock; 1365 } 1366 1367 /* Disable the CSI interface on ANN B0/K0 */ 1368 if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << 1369 ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) { 1370 pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL, 1371 isp->saved_regs.csi_control & ~MRFLD_PCI_CSI_CONTROL_CSI_READY); 1372 } 1373 1374 if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false)) 1375 dev_warn(isp->dev, "DFS failed.\n"); 1376 /* 1377 * ISP work around, need to reset isp 1378 * Is it correct time to reset ISP when first node does streamoff? 1379 */ 1380 if (isp->isp_timeout) 1381 dev_err(isp->dev, "%s: Resetting with WA activated", 1382 __func__); 1383 /* 1384 * It is possible that the other asd stream is in the stage 1385 * that v4l2_setfmt is just get called on it, which will 1386 * create css stream on that stream. But at this point, there 1387 * is no way to destroy the css stream created on that stream. 1388 * 1389 * So force stream destroy here. 1390 */ 1391 if (isp->asd.stream_prepared) { 1392 atomisp_destroy_pipes_stream_force(&isp->asd); 1393 recreate_stream = true; 1394 } 1395 1396 /* disable PUNIT/ISP acknowlede/handshake - SRSE=3 */ 1397 pci_write_config_dword(pdev, PCI_I_CONTROL, 1398 isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK); 1399 dev_err(isp->dev, "atomisp_reset"); 1400 atomisp_reset(isp); 1401 1402 if (recreate_stream) { 1403 int ret2; 1404 1405 ret2 = atomisp_create_pipes_stream(&isp->asd); 1406 if (ret2) { 1407 dev_err(isp->dev, "%s error re-creating streams: %d\n", __func__, ret2); 1408 if (!ret) 1409 ret = ret2; 1410 } 1411 } 1412 1413 isp->isp_timeout = false; 1414 out_unlock: 1415 mutex_unlock(&isp->mutex); 1416 } 1417 1418 /* 1419 * To get the current value of a control. 1420 * applications initialize the id field of a struct v4l2_control and 1421 * call this ioctl with a pointer to this structure 1422 */ 1423 static int atomisp_g_ctrl(struct file *file, void *fh, 1424 struct v4l2_control *control) 1425 { 1426 struct video_device *vdev = video_devdata(file); 1427 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1428 struct atomisp_device *isp = video_get_drvdata(vdev); 1429 int i, ret = -EINVAL; 1430 1431 for (i = 0; i < ctrls_num; i++) { 1432 if (ci_v4l2_controls[i].id == control->id) { 1433 ret = 0; 1434 break; 1435 } 1436 } 1437 1438 if (ret) 1439 return ret; 1440 1441 switch (control->id) { 1442 case V4L2_CID_IRIS_ABSOLUTE: 1443 case V4L2_CID_EXPOSURE_ABSOLUTE: 1444 case V4L2_CID_2A_STATUS: 1445 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: 1446 case V4L2_CID_EXPOSURE: 1447 case V4L2_CID_EXPOSURE_AUTO: 1448 case V4L2_CID_SCENE_MODE: 1449 case V4L2_CID_ISO_SENSITIVITY: 1450 case V4L2_CID_ISO_SENSITIVITY_AUTO: 1451 case V4L2_CID_CONTRAST: 1452 case V4L2_CID_SATURATION: 1453 case V4L2_CID_SHARPNESS: 1454 case V4L2_CID_3A_LOCK: 1455 case V4L2_CID_EXPOSURE_ZONE_NUM: 1456 case V4L2_CID_TEST_PATTERN: 1457 case V4L2_CID_TEST_PATTERN_COLOR_R: 1458 case V4L2_CID_TEST_PATTERN_COLOR_GR: 1459 case V4L2_CID_TEST_PATTERN_COLOR_GB: 1460 case V4L2_CID_TEST_PATTERN_COLOR_B: 1461 return v4l2_g_ctrl(isp->inputs[asd->input_curr].camera-> 1462 ctrl_handler, control); 1463 case V4L2_CID_COLORFX: 1464 ret = atomisp_color_effect(asd, 0, &control->value); 1465 break; 1466 case V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION: 1467 ret = atomisp_bad_pixel(asd, 0, &control->value); 1468 break; 1469 case V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC: 1470 ret = atomisp_gdc_cac(asd, 0, &control->value); 1471 break; 1472 case V4L2_CID_ATOMISP_VIDEO_STABLIZATION: 1473 ret = atomisp_video_stable(asd, 0, &control->value); 1474 break; 1475 case V4L2_CID_ATOMISP_FIXED_PATTERN_NR: 1476 ret = atomisp_fixed_pattern(asd, 0, &control->value); 1477 break; 1478 case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION: 1479 ret = atomisp_false_color(asd, 0, &control->value); 1480 break; 1481 case V4L2_CID_ATOMISP_LOW_LIGHT: 1482 ret = atomisp_low_light(asd, 0, &control->value); 1483 break; 1484 default: 1485 ret = -EINVAL; 1486 break; 1487 } 1488 1489 return ret; 1490 } 1491 1492 /* 1493 * To change the value of a control. 1494 * applications initialize the id and value fields of a struct v4l2_control 1495 * and call this ioctl. 1496 */ 1497 static int atomisp_s_ctrl(struct file *file, void *fh, 1498 struct v4l2_control *control) 1499 { 1500 struct video_device *vdev = video_devdata(file); 1501 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1502 struct atomisp_device *isp = video_get_drvdata(vdev); 1503 int i, ret = -EINVAL; 1504 1505 for (i = 0; i < ctrls_num; i++) { 1506 if (ci_v4l2_controls[i].id == control->id) { 1507 ret = 0; 1508 break; 1509 } 1510 } 1511 1512 if (ret) 1513 return ret; 1514 1515 switch (control->id) { 1516 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE: 1517 case V4L2_CID_EXPOSURE: 1518 case V4L2_CID_EXPOSURE_AUTO: 1519 case V4L2_CID_EXPOSURE_AUTO_PRIORITY: 1520 case V4L2_CID_SCENE_MODE: 1521 case V4L2_CID_ISO_SENSITIVITY: 1522 case V4L2_CID_ISO_SENSITIVITY_AUTO: 1523 case V4L2_CID_POWER_LINE_FREQUENCY: 1524 case V4L2_CID_EXPOSURE_METERING: 1525 case V4L2_CID_CONTRAST: 1526 case V4L2_CID_SATURATION: 1527 case V4L2_CID_SHARPNESS: 1528 case V4L2_CID_3A_LOCK: 1529 case V4L2_CID_COLORFX_CBCR: 1530 case V4L2_CID_TEST_PATTERN: 1531 case V4L2_CID_TEST_PATTERN_COLOR_R: 1532 case V4L2_CID_TEST_PATTERN_COLOR_GR: 1533 case V4L2_CID_TEST_PATTERN_COLOR_GB: 1534 case V4L2_CID_TEST_PATTERN_COLOR_B: 1535 return v4l2_s_ctrl(NULL, 1536 isp->inputs[asd->input_curr].camera-> 1537 ctrl_handler, control); 1538 case V4L2_CID_COLORFX: 1539 ret = atomisp_color_effect(asd, 1, &control->value); 1540 break; 1541 case V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION: 1542 ret = atomisp_bad_pixel(asd, 1, &control->value); 1543 break; 1544 case V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC: 1545 ret = atomisp_gdc_cac(asd, 1, &control->value); 1546 break; 1547 case V4L2_CID_ATOMISP_VIDEO_STABLIZATION: 1548 ret = atomisp_video_stable(asd, 1, &control->value); 1549 break; 1550 case V4L2_CID_ATOMISP_FIXED_PATTERN_NR: 1551 ret = atomisp_fixed_pattern(asd, 1, &control->value); 1552 break; 1553 case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION: 1554 ret = atomisp_false_color(asd, 1, &control->value); 1555 break; 1556 case V4L2_CID_REQUEST_FLASH: 1557 ret = atomisp_flash_enable(asd, control->value); 1558 break; 1559 case V4L2_CID_ATOMISP_LOW_LIGHT: 1560 ret = atomisp_low_light(asd, 1, &control->value); 1561 break; 1562 default: 1563 ret = -EINVAL; 1564 break; 1565 } 1566 return ret; 1567 } 1568 1569 /* 1570 * To query the attributes of a control. 1571 * applications set the id field of a struct v4l2_queryctrl and call the 1572 * this ioctl with a pointer to this structure. The driver fills 1573 * the rest of the structure. 1574 */ 1575 static int atomisp_queryctl(struct file *file, void *fh, 1576 struct v4l2_queryctrl *qc) 1577 { 1578 int i, ret = -EINVAL; 1579 struct video_device *vdev = video_devdata(file); 1580 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1581 struct atomisp_device *isp = video_get_drvdata(vdev); 1582 1583 switch (qc->id) { 1584 case V4L2_CID_FOCUS_ABSOLUTE: 1585 case V4L2_CID_FOCUS_RELATIVE: 1586 case V4L2_CID_FOCUS_STATUS: 1587 if (!IS_ISP2401) { 1588 return v4l2_queryctrl(isp->inputs[asd->input_curr].camera-> 1589 ctrl_handler, qc); 1590 } 1591 /* ISP2401 */ 1592 if (isp->motor) 1593 return v4l2_queryctrl(isp->motor->ctrl_handler, qc); 1594 else 1595 return v4l2_queryctrl(isp->inputs[asd->input_curr]. 1596 camera->ctrl_handler, qc); 1597 } 1598 1599 if (qc->id & V4L2_CTRL_FLAG_NEXT_CTRL) 1600 return ret; 1601 1602 for (i = 0; i < ctrls_num; i++) { 1603 if (ci_v4l2_controls[i].id == qc->id) { 1604 memcpy(qc, &ci_v4l2_controls[i], 1605 sizeof(struct v4l2_queryctrl)); 1606 qc->reserved[0] = 0; 1607 ret = 0; 1608 break; 1609 } 1610 } 1611 if (ret != 0) 1612 qc->flags = V4L2_CTRL_FLAG_DISABLED; 1613 1614 return ret; 1615 } 1616 1617 static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh, 1618 struct v4l2_ext_controls *c) 1619 { 1620 struct video_device *vdev = video_devdata(file); 1621 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1622 struct atomisp_device *isp = video_get_drvdata(vdev); 1623 struct v4l2_subdev *motor; 1624 struct v4l2_control ctrl; 1625 int i; 1626 int ret = 0; 1627 1628 if (!IS_ISP2401) 1629 motor = isp->inputs[asd->input_curr].motor; 1630 else 1631 motor = isp->motor; 1632 1633 for (i = 0; i < c->count; i++) { 1634 ctrl.id = c->controls[i].id; 1635 ctrl.value = c->controls[i].value; 1636 switch (ctrl.id) { 1637 case V4L2_CID_EXPOSURE_ABSOLUTE: 1638 case V4L2_CID_EXPOSURE_AUTO: 1639 case V4L2_CID_IRIS_ABSOLUTE: 1640 case V4L2_CID_3A_LOCK: 1641 case V4L2_CID_TEST_PATTERN: 1642 case V4L2_CID_TEST_PATTERN_COLOR_R: 1643 case V4L2_CID_TEST_PATTERN_COLOR_GR: 1644 case V4L2_CID_TEST_PATTERN_COLOR_GB: 1645 case V4L2_CID_TEST_PATTERN_COLOR_B: 1646 /* 1647 * Exposure related control will be handled by sensor 1648 * driver 1649 */ 1650 ret = 1651 v4l2_g_ctrl(isp->inputs[asd->input_curr].camera-> 1652 ctrl_handler, &ctrl); 1653 break; 1654 case V4L2_CID_FOCUS_ABSOLUTE: 1655 case V4L2_CID_FOCUS_RELATIVE: 1656 case V4L2_CID_FOCUS_STATUS: 1657 case V4L2_CID_FOCUS_AUTO: 1658 if (motor) 1659 ret = v4l2_g_ctrl(motor->ctrl_handler, &ctrl); 1660 break; 1661 case V4L2_CID_FLASH_STATUS: 1662 case V4L2_CID_FLASH_INTENSITY: 1663 case V4L2_CID_FLASH_TORCH_INTENSITY: 1664 case V4L2_CID_FLASH_INDICATOR_INTENSITY: 1665 case V4L2_CID_FLASH_TIMEOUT: 1666 case V4L2_CID_FLASH_STROBE: 1667 case V4L2_CID_FLASH_MODE: 1668 case V4L2_CID_FLASH_STATUS_REGISTER: 1669 if (isp->flash) 1670 ret = 1671 v4l2_g_ctrl(isp->flash->ctrl_handler, 1672 &ctrl); 1673 break; 1674 case V4L2_CID_ZOOM_ABSOLUTE: 1675 ret = atomisp_digital_zoom(asd, 0, &ctrl.value); 1676 break; 1677 case V4L2_CID_G_SKIP_FRAMES: 1678 ret = v4l2_subdev_call( 1679 isp->inputs[asd->input_curr].camera, 1680 sensor, g_skip_frames, (u32 *)&ctrl.value); 1681 break; 1682 default: 1683 ret = -EINVAL; 1684 } 1685 1686 if (ret) { 1687 c->error_idx = i; 1688 break; 1689 } 1690 c->controls[i].value = ctrl.value; 1691 } 1692 return ret; 1693 } 1694 1695 /* This ioctl allows the application to get multiple controls by class */ 1696 static int atomisp_g_ext_ctrls(struct file *file, void *fh, 1697 struct v4l2_ext_controls *c) 1698 { 1699 struct v4l2_control ctrl; 1700 int i, ret = 0; 1701 1702 /* 1703 * input_lock is not need for the Camera related IOCTLs 1704 * The input_lock downgrade the FPS of 3A 1705 */ 1706 ret = atomisp_camera_g_ext_ctrls(file, fh, c); 1707 if (ret != -EINVAL) 1708 return ret; 1709 1710 for (i = 0; i < c->count; i++) { 1711 ctrl.id = c->controls[i].id; 1712 ctrl.value = c->controls[i].value; 1713 ret = atomisp_g_ctrl(file, fh, &ctrl); 1714 c->controls[i].value = ctrl.value; 1715 if (ret) { 1716 c->error_idx = i; 1717 break; 1718 } 1719 } 1720 return ret; 1721 } 1722 1723 static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh, 1724 struct v4l2_ext_controls *c) 1725 { 1726 struct video_device *vdev = video_devdata(file); 1727 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1728 struct atomisp_device *isp = video_get_drvdata(vdev); 1729 struct v4l2_subdev *motor; 1730 struct v4l2_control ctrl; 1731 int i; 1732 int ret = 0; 1733 1734 if (!IS_ISP2401) 1735 motor = isp->inputs[asd->input_curr].motor; 1736 else 1737 motor = isp->motor; 1738 1739 for (i = 0; i < c->count; i++) { 1740 struct v4l2_ctrl *ctr; 1741 1742 ctrl.id = c->controls[i].id; 1743 ctrl.value = c->controls[i].value; 1744 switch (ctrl.id) { 1745 case V4L2_CID_EXPOSURE_ABSOLUTE: 1746 case V4L2_CID_EXPOSURE_AUTO: 1747 case V4L2_CID_EXPOSURE_METERING: 1748 case V4L2_CID_IRIS_ABSOLUTE: 1749 case V4L2_CID_VCM_TIMING: 1750 case V4L2_CID_VCM_SLEW: 1751 case V4L2_CID_3A_LOCK: 1752 case V4L2_CID_TEST_PATTERN: 1753 case V4L2_CID_TEST_PATTERN_COLOR_R: 1754 case V4L2_CID_TEST_PATTERN_COLOR_GR: 1755 case V4L2_CID_TEST_PATTERN_COLOR_GB: 1756 case V4L2_CID_TEST_PATTERN_COLOR_B: 1757 ret = v4l2_s_ctrl(NULL, 1758 isp->inputs[asd->input_curr].camera-> 1759 ctrl_handler, &ctrl); 1760 break; 1761 case V4L2_CID_FOCUS_ABSOLUTE: 1762 case V4L2_CID_FOCUS_RELATIVE: 1763 case V4L2_CID_FOCUS_STATUS: 1764 case V4L2_CID_FOCUS_AUTO: 1765 if (motor) 1766 ret = v4l2_s_ctrl(NULL, motor->ctrl_handler, 1767 &ctrl); 1768 else 1769 ret = v4l2_s_ctrl(NULL, 1770 isp->inputs[asd->input_curr]. 1771 camera->ctrl_handler, &ctrl); 1772 break; 1773 case V4L2_CID_FLASH_STATUS: 1774 case V4L2_CID_FLASH_INTENSITY: 1775 case V4L2_CID_FLASH_TORCH_INTENSITY: 1776 case V4L2_CID_FLASH_INDICATOR_INTENSITY: 1777 case V4L2_CID_FLASH_TIMEOUT: 1778 case V4L2_CID_FLASH_STROBE: 1779 case V4L2_CID_FLASH_MODE: 1780 case V4L2_CID_FLASH_STATUS_REGISTER: 1781 if (isp->flash) { 1782 ret = 1783 v4l2_s_ctrl(NULL, isp->flash->ctrl_handler, 1784 &ctrl); 1785 /* 1786 * When flash mode is changed we need to reset 1787 * flash state 1788 */ 1789 if (ctrl.id == V4L2_CID_FLASH_MODE) { 1790 asd->params.flash_state = 1791 ATOMISP_FLASH_IDLE; 1792 asd->params.num_flash_frames = 0; 1793 } 1794 } 1795 break; 1796 case V4L2_CID_ZOOM_ABSOLUTE: 1797 ret = atomisp_digital_zoom(asd, 1, &ctrl.value); 1798 break; 1799 default: 1800 ctr = v4l2_ctrl_find(&asd->ctrl_handler, ctrl.id); 1801 if (ctr) 1802 ret = v4l2_ctrl_s_ctrl(ctr, ctrl.value); 1803 else 1804 ret = -EINVAL; 1805 } 1806 1807 if (ret) { 1808 c->error_idx = i; 1809 break; 1810 } 1811 c->controls[i].value = ctrl.value; 1812 } 1813 return ret; 1814 } 1815 1816 /* This ioctl allows the application to set multiple controls by class */ 1817 static int atomisp_s_ext_ctrls(struct file *file, void *fh, 1818 struct v4l2_ext_controls *c) 1819 { 1820 struct v4l2_control ctrl; 1821 int i, ret = 0; 1822 1823 /* 1824 * input_lock is not need for the Camera related IOCTLs 1825 * The input_lock downgrade the FPS of 3A 1826 */ 1827 ret = atomisp_camera_s_ext_ctrls(file, fh, c); 1828 if (ret != -EINVAL) 1829 return ret; 1830 1831 for (i = 0; i < c->count; i++) { 1832 ctrl.id = c->controls[i].id; 1833 ctrl.value = c->controls[i].value; 1834 ret = atomisp_s_ctrl(file, fh, &ctrl); 1835 c->controls[i].value = ctrl.value; 1836 if (ret) { 1837 c->error_idx = i; 1838 break; 1839 } 1840 } 1841 return ret; 1842 } 1843 1844 /* 1845 * vidioc_g/s_param are used to switch isp running mode 1846 */ 1847 static int atomisp_g_parm(struct file *file, void *fh, 1848 struct v4l2_streamparm *parm) 1849 { 1850 struct video_device *vdev = video_devdata(file); 1851 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1852 struct atomisp_device *isp = video_get_drvdata(vdev); 1853 1854 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1855 dev_err(isp->dev, "unsupported v4l2 buf type\n"); 1856 return -EINVAL; 1857 } 1858 1859 parm->parm.capture.capturemode = asd->run_mode->val; 1860 1861 return 0; 1862 } 1863 1864 static int atomisp_s_parm(struct file *file, void *fh, 1865 struct v4l2_streamparm *parm) 1866 { 1867 struct video_device *vdev = video_devdata(file); 1868 struct atomisp_device *isp = video_get_drvdata(vdev); 1869 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1870 int mode; 1871 int rval; 1872 int fps; 1873 1874 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1875 dev_err(isp->dev, "unsupported v4l2 buf type\n"); 1876 return -EINVAL; 1877 } 1878 1879 asd->high_speed_mode = false; 1880 switch (parm->parm.capture.capturemode) { 1881 case CI_MODE_NONE: { 1882 struct v4l2_subdev_frame_interval fi = {0}; 1883 1884 fi.interval = parm->parm.capture.timeperframe; 1885 1886 rval = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 1887 video, s_frame_interval, &fi); 1888 if (!rval) 1889 parm->parm.capture.timeperframe = fi.interval; 1890 1891 if (fi.interval.numerator != 0) { 1892 fps = fi.interval.denominator / fi.interval.numerator; 1893 if (fps > 30) 1894 asd->high_speed_mode = true; 1895 } 1896 1897 return rval == -ENOIOCTLCMD ? 0 : rval; 1898 } 1899 case CI_MODE_VIDEO: 1900 mode = ATOMISP_RUN_MODE_VIDEO; 1901 break; 1902 case CI_MODE_STILL_CAPTURE: 1903 mode = ATOMISP_RUN_MODE_STILL_CAPTURE; 1904 break; 1905 case CI_MODE_CONTINUOUS: 1906 mode = ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE; 1907 break; 1908 case CI_MODE_PREVIEW: 1909 mode = ATOMISP_RUN_MODE_PREVIEW; 1910 break; 1911 default: 1912 return -EINVAL; 1913 } 1914 1915 rval = v4l2_ctrl_s_ctrl(asd->run_mode, mode); 1916 1917 return rval == -ENOIOCTLCMD ? 0 : rval; 1918 } 1919 1920 static long atomisp_vidioc_default(struct file *file, void *fh, 1921 bool valid_prio, unsigned int cmd, void *arg) 1922 { 1923 struct video_device *vdev = video_devdata(file); 1924 struct atomisp_device *isp = video_get_drvdata(vdev); 1925 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1926 struct v4l2_subdev *motor; 1927 int err; 1928 1929 if (!IS_ISP2401) 1930 motor = isp->inputs[asd->input_curr].motor; 1931 else 1932 motor = isp->motor; 1933 1934 switch (cmd) { 1935 case ATOMISP_IOC_S_SENSOR_RUNMODE: 1936 if (IS_ISP2401) 1937 err = atomisp_set_sensor_runmode(asd, arg); 1938 else 1939 err = -EINVAL; 1940 break; 1941 1942 case ATOMISP_IOC_G_XNR: 1943 err = atomisp_xnr(asd, 0, arg); 1944 break; 1945 1946 case ATOMISP_IOC_S_XNR: 1947 err = atomisp_xnr(asd, 1, arg); 1948 break; 1949 1950 case ATOMISP_IOC_G_NR: 1951 err = atomisp_nr(asd, 0, arg); 1952 break; 1953 1954 case ATOMISP_IOC_S_NR: 1955 err = atomisp_nr(asd, 1, arg); 1956 break; 1957 1958 case ATOMISP_IOC_G_TNR: 1959 err = atomisp_tnr(asd, 0, arg); 1960 break; 1961 1962 case ATOMISP_IOC_S_TNR: 1963 err = atomisp_tnr(asd, 1, arg); 1964 break; 1965 1966 case ATOMISP_IOC_G_BLACK_LEVEL_COMP: 1967 err = atomisp_black_level(asd, 0, arg); 1968 break; 1969 1970 case ATOMISP_IOC_S_BLACK_LEVEL_COMP: 1971 err = atomisp_black_level(asd, 1, arg); 1972 break; 1973 1974 case ATOMISP_IOC_G_EE: 1975 err = atomisp_ee(asd, 0, arg); 1976 break; 1977 1978 case ATOMISP_IOC_S_EE: 1979 err = atomisp_ee(asd, 1, arg); 1980 break; 1981 1982 case ATOMISP_IOC_G_DIS_STAT: 1983 err = atomisp_get_dis_stat(asd, arg); 1984 break; 1985 1986 case ATOMISP_IOC_G_DVS2_BQ_RESOLUTIONS: 1987 err = atomisp_get_dvs2_bq_resolutions(asd, arg); 1988 break; 1989 1990 case ATOMISP_IOC_S_DIS_COEFS: 1991 err = atomisp_css_cp_dvs2_coefs(asd, arg, 1992 &asd->params.css_param, true); 1993 if (!err && arg) 1994 asd->params.css_update_params_needed = true; 1995 break; 1996 1997 case ATOMISP_IOC_S_DIS_VECTOR: 1998 err = atomisp_cp_dvs_6axis_config(asd, arg, 1999 &asd->params.css_param, true); 2000 if (!err && arg) 2001 asd->params.css_update_params_needed = true; 2002 break; 2003 2004 case ATOMISP_IOC_G_ISP_PARM: 2005 err = atomisp_param(asd, 0, arg); 2006 break; 2007 2008 case ATOMISP_IOC_S_ISP_PARM: 2009 err = atomisp_param(asd, 1, arg); 2010 break; 2011 2012 case ATOMISP_IOC_G_3A_STAT: 2013 err = atomisp_3a_stat(asd, 0, arg); 2014 break; 2015 2016 case ATOMISP_IOC_G_ISP_GAMMA: 2017 err = atomisp_gamma(asd, 0, arg); 2018 break; 2019 2020 case ATOMISP_IOC_S_ISP_GAMMA: 2021 err = atomisp_gamma(asd, 1, arg); 2022 break; 2023 2024 case ATOMISP_IOC_G_ISP_GDC_TAB: 2025 err = atomisp_gdc_cac_table(asd, 0, arg); 2026 break; 2027 2028 case ATOMISP_IOC_S_ISP_GDC_TAB: 2029 err = atomisp_gdc_cac_table(asd, 1, arg); 2030 break; 2031 2032 case ATOMISP_IOC_G_ISP_MACC: 2033 err = atomisp_macc_table(asd, 0, arg); 2034 break; 2035 2036 case ATOMISP_IOC_S_ISP_MACC: 2037 err = atomisp_macc_table(asd, 1, arg); 2038 break; 2039 2040 case ATOMISP_IOC_G_ISP_BAD_PIXEL_DETECTION: 2041 err = atomisp_bad_pixel_param(asd, 0, arg); 2042 break; 2043 2044 case ATOMISP_IOC_S_ISP_BAD_PIXEL_DETECTION: 2045 err = atomisp_bad_pixel_param(asd, 1, arg); 2046 break; 2047 2048 case ATOMISP_IOC_G_ISP_FALSE_COLOR_CORRECTION: 2049 err = atomisp_false_color_param(asd, 0, arg); 2050 break; 2051 2052 case ATOMISP_IOC_S_ISP_FALSE_COLOR_CORRECTION: 2053 err = atomisp_false_color_param(asd, 1, arg); 2054 break; 2055 2056 case ATOMISP_IOC_G_ISP_CTC: 2057 err = atomisp_ctc(asd, 0, arg); 2058 break; 2059 2060 case ATOMISP_IOC_S_ISP_CTC: 2061 err = atomisp_ctc(asd, 1, arg); 2062 break; 2063 2064 case ATOMISP_IOC_G_ISP_WHITE_BALANCE: 2065 err = atomisp_white_balance_param(asd, 0, arg); 2066 break; 2067 2068 case ATOMISP_IOC_S_ISP_WHITE_BALANCE: 2069 err = atomisp_white_balance_param(asd, 1, arg); 2070 break; 2071 2072 case ATOMISP_IOC_G_3A_CONFIG: 2073 err = atomisp_3a_config_param(asd, 0, arg); 2074 break; 2075 2076 case ATOMISP_IOC_S_3A_CONFIG: 2077 err = atomisp_3a_config_param(asd, 1, arg); 2078 break; 2079 2080 case ATOMISP_IOC_S_ISP_FPN_TABLE: 2081 err = atomisp_fixed_pattern_table(asd, arg); 2082 break; 2083 2084 case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA: 2085 if (motor) 2086 err = v4l2_subdev_call(motor, core, ioctl, cmd, arg); 2087 else 2088 err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 2089 core, ioctl, cmd, arg); 2090 break; 2091 2092 case ATOMISP_IOC_S_EXPOSURE: 2093 case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP: 2094 case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA: 2095 case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO: 2096 case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE: 2097 case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE: 2098 case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT: 2099 err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 2100 core, ioctl, cmd, arg); 2101 break; 2102 case ATOMISP_IOC_G_UPDATE_EXPOSURE: 2103 if (IS_ISP2401) 2104 err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 2105 core, ioctl, cmd, arg); 2106 else 2107 err = -EINVAL; 2108 break; 2109 2110 case ATOMISP_IOC_S_ISP_SHD_TAB: 2111 err = atomisp_set_shading_table(asd, arg); 2112 break; 2113 2114 case ATOMISP_IOC_G_ISP_GAMMA_CORRECTION: 2115 err = atomisp_gamma_correction(asd, 0, arg); 2116 break; 2117 2118 case ATOMISP_IOC_S_ISP_GAMMA_CORRECTION: 2119 err = atomisp_gamma_correction(asd, 1, arg); 2120 break; 2121 2122 case ATOMISP_IOC_S_PARAMETERS: 2123 err = atomisp_set_parameters(vdev, arg); 2124 break; 2125 2126 case ATOMISP_IOC_G_METADATA: 2127 err = atomisp_get_metadata(asd, 0, arg); 2128 break; 2129 case ATOMISP_IOC_G_METADATA_BY_TYPE: 2130 err = atomisp_get_metadata_by_type(asd, 0, arg); 2131 break; 2132 case ATOMISP_IOC_EXT_ISP_CTRL: 2133 err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 2134 core, ioctl, cmd, arg); 2135 break; 2136 case ATOMISP_IOC_EXP_ID_UNLOCK: 2137 err = atomisp_exp_id_unlock(asd, arg); 2138 break; 2139 case ATOMISP_IOC_EXP_ID_CAPTURE: 2140 err = atomisp_exp_id_capture(asd, arg); 2141 break; 2142 case ATOMISP_IOC_S_ENABLE_DZ_CAPT_PIPE: 2143 err = atomisp_enable_dz_capt_pipe(asd, arg); 2144 break; 2145 case ATOMISP_IOC_G_FORMATS_CONFIG: 2146 err = atomisp_formats(asd, 0, arg); 2147 break; 2148 2149 case ATOMISP_IOC_S_FORMATS_CONFIG: 2150 err = atomisp_formats(asd, 1, arg); 2151 break; 2152 case ATOMISP_IOC_S_EXPOSURE_WINDOW: 2153 err = atomisp_s_ae_window(asd, arg); 2154 break; 2155 case ATOMISP_IOC_INJECT_A_FAKE_EVENT: 2156 err = atomisp_inject_a_fake_event(asd, arg); 2157 break; 2158 case ATOMISP_IOC_G_INVALID_FRAME_NUM: 2159 err = atomisp_get_invalid_frame_num(vdev, arg); 2160 break; 2161 case ATOMISP_IOC_S_ARRAY_RESOLUTION: 2162 err = atomisp_set_array_res(asd, arg); 2163 break; 2164 default: 2165 err = -EINVAL; 2166 break; 2167 } 2168 2169 return err; 2170 } 2171 2172 const struct v4l2_ioctl_ops atomisp_ioctl_ops = { 2173 .vidioc_querycap = atomisp_querycap, 2174 .vidioc_enum_input = atomisp_enum_input, 2175 .vidioc_g_input = atomisp_g_input, 2176 .vidioc_s_input = atomisp_s_input, 2177 .vidioc_queryctrl = atomisp_queryctl, 2178 .vidioc_s_ctrl = atomisp_s_ctrl, 2179 .vidioc_g_ctrl = atomisp_g_ctrl, 2180 .vidioc_s_ext_ctrls = atomisp_s_ext_ctrls, 2181 .vidioc_g_ext_ctrls = atomisp_g_ext_ctrls, 2182 .vidioc_enum_framesizes = atomisp_enum_framesizes, 2183 .vidioc_enum_frameintervals = atomisp_enum_frameintervals, 2184 .vidioc_enum_fmt_vid_cap = atomisp_enum_fmt_cap, 2185 .vidioc_try_fmt_vid_cap = atomisp_try_fmt_cap, 2186 .vidioc_g_fmt_vid_cap = atomisp_g_fmt_cap, 2187 .vidioc_s_fmt_vid_cap = atomisp_s_fmt_cap, 2188 .vidioc_reqbufs = vb2_ioctl_reqbufs, 2189 .vidioc_querybuf = vb2_ioctl_querybuf, 2190 .vidioc_qbuf = atomisp_qbuf_wrapper, 2191 .vidioc_dqbuf = atomisp_dqbuf_wrapper, 2192 .vidioc_streamon = vb2_ioctl_streamon, 2193 .vidioc_streamoff = vb2_ioctl_streamoff, 2194 .vidioc_default = atomisp_vidioc_default, 2195 .vidioc_s_parm = atomisp_s_parm, 2196 .vidioc_g_parm = atomisp_g_parm, 2197 }; 2198