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