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_COLORFX, 87 .type = V4L2_CTRL_TYPE_INTEGER, 88 .name = "Image Color Effect", 89 .minimum = 0, 90 .maximum = 9, 91 .step = 1, 92 .default_value = 0, 93 }, 94 { 95 .id = V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION, 96 .type = V4L2_CTRL_TYPE_INTEGER, 97 .name = "Bad Pixel Correction", 98 .minimum = 0, 99 .maximum = 1, 100 .step = 1, 101 .default_value = 0, 102 }, 103 { 104 .id = V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC, 105 .type = V4L2_CTRL_TYPE_INTEGER, 106 .name = "GDC/CAC", 107 .minimum = 0, 108 .maximum = 1, 109 .step = 1, 110 .default_value = 0, 111 }, 112 { 113 .id = V4L2_CID_ATOMISP_VIDEO_STABLIZATION, 114 .type = V4L2_CTRL_TYPE_INTEGER, 115 .name = "Video Stablization", 116 .minimum = 0, 117 .maximum = 1, 118 .step = 1, 119 .default_value = 0, 120 }, 121 { 122 .id = V4L2_CID_ATOMISP_FIXED_PATTERN_NR, 123 .type = V4L2_CTRL_TYPE_INTEGER, 124 .name = "Fixed Pattern Noise Reduction", 125 .minimum = 0, 126 .maximum = 1, 127 .step = 1, 128 .default_value = 0, 129 }, 130 { 131 .id = V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION, 132 .type = V4L2_CTRL_TYPE_INTEGER, 133 .name = "False Color Correction", 134 .minimum = 0, 135 .maximum = 1, 136 .step = 1, 137 .default_value = 0, 138 }, 139 { 140 .id = V4L2_CID_ATOMISP_LOW_LIGHT, 141 .type = V4L2_CTRL_TYPE_BOOLEAN, 142 .name = "Low light mode", 143 .minimum = 0, 144 .maximum = 1, 145 .step = 1, 146 .default_value = 1, 147 }, 148 }; 149 150 static const u32 ctrls_num = ARRAY_SIZE(ci_v4l2_controls); 151 152 /* 153 * supported V4L2 fmts and resolutions 154 */ 155 const struct atomisp_format_bridge atomisp_output_fmts[] = { 156 { 157 .pixelformat = V4L2_PIX_FMT_YUV420, 158 .depth = 12, 159 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV420, 160 .sh_fmt = IA_CSS_FRAME_FORMAT_YUV420, 161 .description = "YUV420, planar", 162 .planar = true 163 }, { 164 .pixelformat = V4L2_PIX_FMT_YVU420, 165 .depth = 12, 166 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YVU420, 167 .sh_fmt = IA_CSS_FRAME_FORMAT_YV12, 168 .description = "YVU420, planar", 169 .planar = true 170 }, { 171 .pixelformat = V4L2_PIX_FMT_YUV422P, 172 .depth = 16, 173 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV422P, 174 .sh_fmt = IA_CSS_FRAME_FORMAT_YUV422, 175 .description = "YUV422, planar", 176 .planar = true 177 }, { 178 .pixelformat = V4L2_PIX_FMT_YUV444, 179 .depth = 24, 180 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV444, 181 .sh_fmt = IA_CSS_FRAME_FORMAT_YUV444, 182 .description = "YUV444" 183 }, { 184 .pixelformat = V4L2_PIX_FMT_NV12, 185 .depth = 12, 186 .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV12, 187 .sh_fmt = IA_CSS_FRAME_FORMAT_NV12, 188 .description = "NV12, Y-plane, CbCr interleaved", 189 .planar = true 190 }, { 191 .pixelformat = V4L2_PIX_FMT_NV21, 192 .depth = 12, 193 .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV21, 194 .sh_fmt = IA_CSS_FRAME_FORMAT_NV21, 195 .description = "NV21, Y-plane, CbCr interleaved", 196 .planar = true 197 }, { 198 .pixelformat = V4L2_PIX_FMT_NV16, 199 .depth = 16, 200 .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV16, 201 .sh_fmt = IA_CSS_FRAME_FORMAT_NV16, 202 .description = "NV16, Y-plane, CbCr interleaved", 203 .planar = true 204 }, { 205 .pixelformat = V4L2_PIX_FMT_YUYV, 206 .depth = 16, 207 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUYV, 208 .sh_fmt = IA_CSS_FRAME_FORMAT_YUYV, 209 .description = "YUYV, interleaved" 210 }, { 211 .pixelformat = V4L2_PIX_FMT_UYVY, 212 .depth = 16, 213 .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16, 214 .sh_fmt = IA_CSS_FRAME_FORMAT_UYVY, 215 .description = "UYVY, interleaved" 216 }, { 217 .pixelformat = V4L2_PIX_FMT_SBGGR16, 218 .depth = 16, 219 .mbus_code = V4L2_MBUS_FMT_CUSTOM_SBGGR16, 220 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 221 .description = "Bayer 16" 222 }, { 223 .pixelformat = V4L2_PIX_FMT_SBGGR8, 224 .depth = 8, 225 .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, 226 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 227 .description = "Bayer 8" 228 }, { 229 .pixelformat = V4L2_PIX_FMT_SGBRG8, 230 .depth = 8, 231 .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, 232 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 233 .description = "Bayer 8" 234 }, { 235 .pixelformat = V4L2_PIX_FMT_SGRBG8, 236 .depth = 8, 237 .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, 238 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 239 .description = "Bayer 8" 240 }, { 241 .pixelformat = V4L2_PIX_FMT_SRGGB8, 242 .depth = 8, 243 .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, 244 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 245 .description = "Bayer 8" 246 }, { 247 .pixelformat = V4L2_PIX_FMT_SBGGR10, 248 .depth = 16, 249 .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, 250 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 251 .description = "Bayer 10" 252 }, { 253 .pixelformat = V4L2_PIX_FMT_SGBRG10, 254 .depth = 16, 255 .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, 256 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 257 .description = "Bayer 10" 258 }, { 259 .pixelformat = V4L2_PIX_FMT_SGRBG10, 260 .depth = 16, 261 .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, 262 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 263 .description = "Bayer 10" 264 }, { 265 .pixelformat = V4L2_PIX_FMT_SRGGB10, 266 .depth = 16, 267 .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, 268 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 269 .description = "Bayer 10" 270 }, { 271 .pixelformat = V4L2_PIX_FMT_SBGGR12, 272 .depth = 16, 273 .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, 274 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 275 .description = "Bayer 12" 276 }, { 277 .pixelformat = V4L2_PIX_FMT_SGBRG12, 278 .depth = 16, 279 .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, 280 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 281 .description = "Bayer 12" 282 }, { 283 .pixelformat = V4L2_PIX_FMT_SGRBG12, 284 .depth = 16, 285 .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, 286 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 287 .description = "Bayer 12" 288 }, { 289 .pixelformat = V4L2_PIX_FMT_SRGGB12, 290 .depth = 16, 291 .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, 292 .sh_fmt = IA_CSS_FRAME_FORMAT_RAW, 293 .description = "Bayer 12" 294 }, { 295 .pixelformat = V4L2_PIX_FMT_RGB565, 296 .depth = 16, 297 .mbus_code = MEDIA_BUS_FMT_BGR565_2X8_LE, 298 .sh_fmt = IA_CSS_FRAME_FORMAT_RGB565, 299 .description = "16 RGB 5-6-5" 300 #if 0 301 }, { 302 /* 303 * Broken, showing vertical columns with random data. 304 * For each 128 pixels in a row the last 28 (32?) or so pixels 305 * contain random data. 306 */ 307 .pixelformat = V4L2_PIX_FMT_RGBX32, 308 .depth = 32, 309 .mbus_code = V4L2_MBUS_FMT_CUSTOM_RGB32, 310 .sh_fmt = IA_CSS_FRAME_FORMAT_RGBA888, 311 .description = "32 RGB 8-8-8-8" 312 }, { 313 .pixelformat = V4L2_PIX_FMT_JPEG, 314 .depth = 8, 315 .mbus_code = MEDIA_BUS_FMT_JPEG_1X8, 316 .sh_fmt = IA_CSS_FRAME_FORMAT_BINARY_8, 317 .description = "JPEG" 318 }, { 319 /* This is a custom format being used by M10MO to send the RAW data */ 320 .pixelformat = V4L2_PIX_FMT_CUSTOM_M10MO_RAW, 321 .depth = 8, 322 .mbus_code = V4L2_MBUS_FMT_CUSTOM_M10MO_RAW, 323 .sh_fmt = IA_CSS_FRAME_FORMAT_BINARY_8, 324 .description = "Custom RAW for M10MO" 325 #endif 326 }, 327 }; 328 329 const struct atomisp_format_bridge * atomisp_get_format_bridge(unsigned int pixelformat)330 atomisp_get_format_bridge(unsigned int pixelformat) 331 { 332 unsigned int i; 333 334 for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) { 335 if (atomisp_output_fmts[i].pixelformat == pixelformat) 336 return &atomisp_output_fmts[i]; 337 } 338 339 return NULL; 340 } 341 342 const struct atomisp_format_bridge * atomisp_get_format_bridge_from_mbus(u32 mbus_code)343 atomisp_get_format_bridge_from_mbus(u32 mbus_code) 344 { 345 unsigned int i; 346 347 for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) { 348 if (mbus_code == atomisp_output_fmts[i].mbus_code) 349 return &atomisp_output_fmts[i]; 350 } 351 352 return NULL; 353 } 354 atomisp_pipe_check(struct atomisp_video_pipe * pipe,bool settings_change)355 int atomisp_pipe_check(struct atomisp_video_pipe *pipe, bool settings_change) 356 { 357 lockdep_assert_held(&pipe->isp->mutex); 358 359 if (pipe->isp->isp_fatal_error) 360 return -EIO; 361 362 if (settings_change && vb2_is_busy(&pipe->vb_queue)) { 363 dev_err(pipe->isp->dev, "Set fmt/input IOCTL while streaming\n"); 364 return -EBUSY; 365 } 366 367 return 0; 368 } 369 370 /* 371 * v4l2 ioctls 372 * return ISP capabilities 373 */ atomisp_querycap(struct file * file,void * fh,struct v4l2_capability * cap)374 static int atomisp_querycap(struct file *file, void *fh, 375 struct v4l2_capability *cap) 376 { 377 struct video_device *vdev = video_devdata(file); 378 struct atomisp_device *isp = video_get_drvdata(vdev); 379 380 strscpy(cap->driver, DRIVER, sizeof(cap->driver)); 381 strscpy(cap->card, CARD, sizeof(cap->card)); 382 snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s", dev_name(isp->dev)); 383 384 return 0; 385 } 386 387 /* 388 * enum input are used to check primary/secondary camera 389 */ atomisp_enum_input(struct file * file,void * fh,struct v4l2_input * input)390 static int atomisp_enum_input(struct file *file, void *fh, 391 struct v4l2_input *input) 392 { 393 struct video_device *vdev = video_devdata(file); 394 struct atomisp_device *isp = video_get_drvdata(vdev); 395 int index = input->index; 396 397 if (index >= isp->input_cnt) 398 return -EINVAL; 399 400 if (!isp->inputs[index].camera) 401 return -EINVAL; 402 403 memset(input, 0, sizeof(struct v4l2_input)); 404 strscpy(input->name, isp->inputs[index].camera->name, 405 sizeof(input->name)); 406 407 input->type = V4L2_INPUT_TYPE_CAMERA; 408 input->index = index; 409 input->reserved[1] = isp->inputs[index].port; 410 411 return 0; 412 } 413 414 /* 415 * get input are used to get current primary/secondary camera 416 */ atomisp_g_input(struct file * file,void * fh,unsigned int * input)417 static int atomisp_g_input(struct file *file, void *fh, unsigned int *input) 418 { 419 struct video_device *vdev = video_devdata(file); 420 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 421 422 *input = asd->input_curr; 423 return 0; 424 } 425 atomisp_s_fmt_cap(struct file * file,void * fh,struct v4l2_format * f)426 static int atomisp_s_fmt_cap(struct file *file, void *fh, 427 struct v4l2_format *f) 428 { 429 struct video_device *vdev = video_devdata(file); 430 431 return atomisp_set_fmt(vdev, f); 432 } 433 434 /* 435 * set input are used to set current primary/secondary camera 436 */ atomisp_s_input(struct file * file,void * fh,unsigned int input)437 static int atomisp_s_input(struct file *file, void *fh, unsigned int input) 438 { 439 struct video_device *vdev = video_devdata(file); 440 struct atomisp_device *isp = video_get_drvdata(vdev); 441 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 442 int ret; 443 444 if (input >= isp->input_cnt) 445 return -EINVAL; 446 447 if (!isp->inputs[input].camera) 448 return -EINVAL; 449 450 ret = atomisp_pipe_check(pipe, true); 451 if (ret) 452 return ret; 453 454 mutex_lock(&isp->media_dev.graph_mutex); 455 ret = atomisp_select_input(isp, input); 456 mutex_unlock(&isp->media_dev.graph_mutex); 457 458 return ret; 459 } 460 461 /* 462 * With crop any framesize <= sensor-size can be made, give 463 * userspace a list of sizes to choice from. 464 */ atomisp_enum_framesizes_crop_inner(struct atomisp_device * isp,struct v4l2_frmsizeenum * fsize,const struct v4l2_rect * active,const struct v4l2_rect * native,int * valid_sizes)465 static int atomisp_enum_framesizes_crop_inner(struct atomisp_device *isp, 466 struct v4l2_frmsizeenum *fsize, 467 const struct v4l2_rect *active, 468 const struct v4l2_rect *native, 469 int *valid_sizes) 470 { 471 static const struct v4l2_frmsize_discrete frame_sizes[] = { 472 { 1920, 1440 }, 473 { 1920, 1200 }, 474 { 1920, 1080 }, 475 { 1600, 1200 }, 476 { 1600, 1080 }, 477 { 1600, 900 }, 478 { 1440, 1080 }, 479 { 1280, 960 }, 480 { 1280, 720 }, 481 { 800, 600 }, 482 { 640, 480 }, 483 }; 484 u32 padding_w, padding_h; 485 int i; 486 487 for (i = 0; i < ARRAY_SIZE(frame_sizes); i++) { 488 atomisp_get_padding(isp, frame_sizes[i].width, frame_sizes[i].height, 489 &padding_w, &padding_h); 490 491 if ((frame_sizes[i].width + padding_w) > native->width || 492 (frame_sizes[i].height + padding_h) > native->height) 493 continue; 494 495 /* 496 * Skip sizes where width and height are less then 5/8th of the 497 * sensor size to avoid sizes with a too small field of view. 498 */ 499 if (frame_sizes[i].width < (active->width * 5 / 8) && 500 frame_sizes[i].height < (active->height * 5 / 8)) 501 continue; 502 503 if (*valid_sizes == fsize->index) { 504 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; 505 fsize->discrete = frame_sizes[i]; 506 return 0; 507 } 508 509 (*valid_sizes)++; 510 } 511 512 return -EINVAL; 513 } 514 atomisp_enum_framesizes_crop(struct atomisp_device * isp,struct v4l2_frmsizeenum * fsize)515 static int atomisp_enum_framesizes_crop(struct atomisp_device *isp, 516 struct v4l2_frmsizeenum *fsize) 517 { 518 struct atomisp_input_subdev *input = &isp->inputs[isp->asd.input_curr]; 519 struct v4l2_rect active = input->active_rect; 520 struct v4l2_rect native = input->native_rect; 521 int ret, valid_sizes = 0; 522 523 ret = atomisp_enum_framesizes_crop_inner(isp, fsize, &active, &native, &valid_sizes); 524 if (ret == 0) 525 return 0; 526 527 if (!input->binning_support) 528 return -EINVAL; 529 530 active.width /= 2; 531 active.height /= 2; 532 native.width /= 2; 533 native.height /= 2; 534 535 return atomisp_enum_framesizes_crop_inner(isp, fsize, &active, &native, &valid_sizes); 536 } 537 atomisp_enum_framesizes(struct file * file,void * priv,struct v4l2_frmsizeenum * fsize)538 static int atomisp_enum_framesizes(struct file *file, void *priv, 539 struct v4l2_frmsizeenum *fsize) 540 { 541 struct video_device *vdev = video_devdata(file); 542 struct atomisp_device *isp = video_get_drvdata(vdev); 543 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 544 struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr]; 545 struct v4l2_subdev_frame_size_enum fse = { 546 .index = fsize->index, 547 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 548 .code = input->code, 549 }; 550 struct v4l2_subdev_state *act_sd_state; 551 int ret; 552 553 if (!input->camera) 554 return -EINVAL; 555 556 if (input->crop_support) 557 return atomisp_enum_framesizes_crop(isp, fsize); 558 559 act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); 560 ret = v4l2_subdev_call(input->camera, pad, enum_frame_size, 561 act_sd_state, &fse); 562 if (act_sd_state) 563 v4l2_subdev_unlock_state(act_sd_state); 564 if (ret) 565 return ret; 566 567 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; 568 fsize->discrete.width = fse.max_width - pad_w; 569 fsize->discrete.height = fse.max_height - pad_h; 570 571 return 0; 572 } 573 atomisp_enum_frameintervals(struct file * file,void * priv,struct v4l2_frmivalenum * fival)574 static int atomisp_enum_frameintervals(struct file *file, void *priv, 575 struct v4l2_frmivalenum *fival) 576 { 577 struct video_device *vdev = video_devdata(file); 578 struct atomisp_device *isp = video_get_drvdata(vdev); 579 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 580 struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr]; 581 struct v4l2_subdev_frame_interval_enum fie = { 582 .code = atomisp_in_fmt_conv[0].code, 583 .index = fival->index, 584 .width = fival->width, 585 .height = fival->height, 586 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 587 }; 588 struct v4l2_subdev_state *act_sd_state; 589 int ret; 590 591 if (!input->camera) 592 return -EINVAL; 593 594 act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); 595 ret = v4l2_subdev_call(input->camera, pad, enum_frame_interval, 596 act_sd_state, &fie); 597 if (act_sd_state) 598 v4l2_subdev_unlock_state(act_sd_state); 599 if (ret) 600 return ret; 601 602 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; 603 fival->discrete = fie.interval; 604 605 return ret; 606 } 607 atomisp_enum_fmt_cap(struct file * file,void * fh,struct v4l2_fmtdesc * f)608 static int atomisp_enum_fmt_cap(struct file *file, void *fh, 609 struct v4l2_fmtdesc *f) 610 { 611 struct video_device *vdev = video_devdata(file); 612 struct atomisp_device *isp = video_get_drvdata(vdev); 613 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 614 struct atomisp_input_subdev *input = &isp->inputs[asd->input_curr]; 615 struct v4l2_subdev_mbus_code_enum code = { 616 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 617 }; 618 const struct atomisp_format_bridge *format; 619 struct v4l2_subdev_state *act_sd_state; 620 unsigned int i, fi = 0; 621 int ret; 622 623 if (!input->camera) 624 return -EINVAL; 625 626 act_sd_state = v4l2_subdev_lock_and_get_active_state(input->camera); 627 ret = v4l2_subdev_call(input->camera, pad, enum_mbus_code, 628 act_sd_state, &code); 629 if (act_sd_state) 630 v4l2_subdev_unlock_state(act_sd_state); 631 if (ret) 632 return ret; 633 634 for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) { 635 format = &atomisp_output_fmts[i]; 636 637 /* 638 * Is the atomisp-supported format is valid for the 639 * sensor (configuration)? If not, skip it. 640 * 641 * FIXME: fix the pipeline to allow sensor format too. 642 */ 643 if (format->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) 644 continue; 645 646 /* Found a match. Now let's pick f->index'th one. */ 647 if (fi < f->index) { 648 fi++; 649 continue; 650 } 651 652 strscpy(f->description, format->description, 653 sizeof(f->description)); 654 f->pixelformat = format->pixelformat; 655 return 0; 656 } 657 658 return -EINVAL; 659 } 660 661 /* This function looks up the closest available resolution. */ atomisp_try_fmt_cap(struct file * file,void * fh,struct v4l2_format * f)662 static int atomisp_try_fmt_cap(struct file *file, void *fh, 663 struct v4l2_format *f) 664 { 665 struct video_device *vdev = video_devdata(file); 666 struct atomisp_device *isp = video_get_drvdata(vdev); 667 668 return atomisp_try_fmt(isp, &f->fmt.pix, NULL, NULL); 669 } 670 atomisp_g_fmt_cap(struct file * file,void * fh,struct v4l2_format * f)671 static int atomisp_g_fmt_cap(struct file *file, void *fh, 672 struct v4l2_format *f) 673 { 674 struct video_device *vdev = video_devdata(file); 675 struct atomisp_video_pipe *pipe; 676 677 pipe = atomisp_to_video_pipe(vdev); 678 679 f->fmt.pix = pipe->pix; 680 681 /* If s_fmt was issued, just return whatever is was previouly set */ 682 if (f->fmt.pix.sizeimage) 683 return 0; 684 685 f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; 686 f->fmt.pix.width = 10000; 687 f->fmt.pix.height = 10000; 688 689 return atomisp_try_fmt_cap(file, fh, f); 690 } 691 atomisp_alloc_css_stat_bufs(struct atomisp_sub_device * asd,uint16_t stream_id)692 int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd, 693 uint16_t stream_id) 694 { 695 struct atomisp_device *isp = asd->isp; 696 struct atomisp_s3a_buf *s3a_buf = NULL, *_s3a_buf; 697 struct atomisp_dis_buf *dis_buf = NULL, *_dis_buf; 698 struct atomisp_metadata_buf *md_buf = NULL, *_md_buf; 699 int count; 700 struct ia_css_dvs_grid_info *dvs_grid_info = 701 atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info); 702 unsigned int i; 703 704 if (list_empty(&asd->s3a_stats) && 705 asd->params.curr_grid_info.s3a_grid.enable) { 706 count = ATOMISP_CSS_Q_DEPTH + 707 ATOMISP_S3A_BUF_QUEUE_DEPTH_FOR_HAL; 708 dev_dbg(isp->dev, "allocating %d 3a buffers\n", count); 709 while (count--) { 710 s3a_buf = kzalloc(sizeof(struct atomisp_s3a_buf), GFP_KERNEL); 711 if (!s3a_buf) 712 goto error; 713 714 if (atomisp_css_allocate_stat_buffers( 715 asd, stream_id, s3a_buf, NULL, NULL)) { 716 kfree(s3a_buf); 717 goto error; 718 } 719 720 list_add_tail(&s3a_buf->list, &asd->s3a_stats); 721 } 722 } 723 724 if (list_empty(&asd->dis_stats) && dvs_grid_info && 725 dvs_grid_info->enable) { 726 count = ATOMISP_CSS_Q_DEPTH + 1; 727 dev_dbg(isp->dev, "allocating %d dis buffers\n", count); 728 while (count--) { 729 dis_buf = kzalloc(sizeof(struct atomisp_dis_buf), GFP_KERNEL); 730 if (!dis_buf) 731 goto error; 732 if (atomisp_css_allocate_stat_buffers( 733 asd, stream_id, NULL, dis_buf, NULL)) { 734 kfree(dis_buf); 735 goto error; 736 } 737 738 list_add_tail(&dis_buf->list, &asd->dis_stats); 739 } 740 } 741 742 for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) { 743 if (list_empty(&asd->metadata[i]) && 744 list_empty(&asd->metadata_ready[i]) && 745 list_empty(&asd->metadata_in_css[i])) { 746 count = ATOMISP_CSS_Q_DEPTH + 747 ATOMISP_METADATA_QUEUE_DEPTH_FOR_HAL; 748 dev_dbg(isp->dev, "allocating %d metadata buffers for type %d\n", 749 count, i); 750 while (count--) { 751 md_buf = kzalloc(sizeof(struct atomisp_metadata_buf), 752 GFP_KERNEL); 753 if (!md_buf) 754 goto error; 755 756 if (atomisp_css_allocate_stat_buffers( 757 asd, stream_id, NULL, NULL, md_buf)) { 758 kfree(md_buf); 759 goto error; 760 } 761 list_add_tail(&md_buf->list, &asd->metadata[i]); 762 } 763 } 764 } 765 return 0; 766 767 error: 768 dev_err(isp->dev, "failed to allocate statistics buffers\n"); 769 770 list_for_each_entry_safe(dis_buf, _dis_buf, &asd->dis_stats, list) { 771 atomisp_css_free_dis_buffer(dis_buf); 772 list_del(&dis_buf->list); 773 kfree(dis_buf); 774 } 775 776 list_for_each_entry_safe(s3a_buf, _s3a_buf, &asd->s3a_stats, list) { 777 atomisp_css_free_3a_buffer(s3a_buf); 778 list_del(&s3a_buf->list); 779 kfree(s3a_buf); 780 } 781 782 for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) { 783 list_for_each_entry_safe(md_buf, _md_buf, &asd->metadata[i], 784 list) { 785 atomisp_css_free_metadata_buffer(md_buf); 786 list_del(&md_buf->list); 787 kfree(md_buf); 788 } 789 } 790 return -ENOMEM; 791 } 792 793 /* 794 * FIXME the abuse of buf->reserved2 in the qbuf and dqbuf wrappers comes from 795 * the original atomisp buffer handling and should be replaced with proper V4L2 796 * per frame parameters use. 797 * 798 * Once this is fixed these wrappers can be removed, replacing them with direct 799 * calls to vb2_ioctl_[d]qbuf(). 800 */ atomisp_qbuf_wrapper(struct file * file,void * fh,struct v4l2_buffer * buf)801 static int atomisp_qbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer *buf) 802 { 803 struct video_device *vdev = video_devdata(file); 804 struct atomisp_device *isp = video_get_drvdata(vdev); 805 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 806 807 if (buf->index >= vb2_get_num_buffers(vdev->queue)) 808 return -EINVAL; 809 810 if (buf->reserved2 & ATOMISP_BUFFER_HAS_PER_FRAME_SETTING) { 811 /* this buffer will have a per-frame parameter */ 812 pipe->frame_request_config_id[buf->index] = buf->reserved2 & 813 ~ATOMISP_BUFFER_HAS_PER_FRAME_SETTING; 814 dev_dbg(isp->dev, 815 "This buffer requires per_frame setting which has isp_config_id %d\n", 816 pipe->frame_request_config_id[buf->index]); 817 } else { 818 pipe->frame_request_config_id[buf->index] = 0; 819 } 820 821 return vb2_ioctl_qbuf(file, fh, buf); 822 } 823 atomisp_dqbuf_wrapper(struct file * file,void * fh,struct v4l2_buffer * buf)824 static int atomisp_dqbuf_wrapper(struct file *file, void *fh, struct v4l2_buffer *buf) 825 { 826 struct video_device *vdev = video_devdata(file); 827 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); 828 struct atomisp_device *isp = video_get_drvdata(vdev); 829 struct ia_css_frame *frame; 830 struct vb2_buffer *vb; 831 int ret; 832 833 ret = vb2_ioctl_dqbuf(file, fh, buf); 834 if (ret) 835 return ret; 836 837 vb = vb2_get_buffer(&pipe->vb_queue, buf->index); 838 frame = vb_to_frame(vb); 839 840 /* reserved bit[31:16] is used for exp_id */ 841 buf->reserved = 0; 842 if (!(buf->flags & V4L2_BUF_FLAG_ERROR)) 843 buf->reserved |= frame->exp_id; 844 buf->reserved2 = pipe->frame_config_id[buf->index]; 845 846 dev_dbg(isp->dev, 847 "dqbuf buffer %d (%s) with exp_id %d, isp_config_id %d\n", 848 buf->index, vdev->name, buf->reserved >> 16, buf->reserved2); 849 return 0; 850 } 851 852 /* Input system HW workaround */ 853 /* Input system address translation corrupts burst during */ 854 /* invalidate. SW workaround for this is to set burst length */ 855 /* manually to 128 in case of 13MPx snapshot and to 1 otherwise. */ atomisp_dma_burst_len_cfg(struct atomisp_sub_device * asd)856 static void atomisp_dma_burst_len_cfg(struct atomisp_sub_device *asd) 857 { 858 struct v4l2_mbus_framefmt *sink; 859 860 sink = atomisp_subdev_get_ffmt(&asd->subdev, NULL, 861 V4L2_SUBDEV_FORMAT_ACTIVE, 862 ATOMISP_SUBDEV_PAD_SINK); 863 864 if (sink->width * sink->height >= 4096 * 3072) 865 atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x7F); 866 else 867 atomisp_css2_hw_store_32(DMA_BURST_SIZE_REG, 0x00); 868 } 869 atomisp_start_streaming(struct vb2_queue * vq,unsigned int count)870 int atomisp_start_streaming(struct vb2_queue *vq, unsigned int count) 871 { 872 struct atomisp_video_pipe *pipe = vq_to_pipe(vq); 873 struct atomisp_sub_device *asd = pipe->asd; 874 struct atomisp_device *isp = asd->isp; 875 struct pci_dev *pdev = to_pci_dev(isp->dev); 876 unsigned long irqflags; 877 int ret; 878 879 dev_dbg(isp->dev, "Start stream\n"); 880 881 mutex_lock(&isp->mutex); 882 883 ret = atomisp_pipe_check(pipe, false); 884 if (ret) 885 goto out_unlock; 886 887 /* 888 * When running a classic v4l2 app after a media-controller aware 889 * app, the CSI-receiver -> ISP link for the current sensor may be 890 * disabled. Fix this up before marking the pipeline as started. 891 */ 892 mutex_lock(&isp->media_dev.graph_mutex); 893 atomisp_setup_input_links(isp); 894 ret = __media_pipeline_start(&asd->video_out.vdev.entity.pads[0], &asd->video_out.pipe); 895 mutex_unlock(&isp->media_dev.graph_mutex); 896 if (ret) { 897 dev_err(isp->dev, "Error starting mc pipeline: %d\n", ret); 898 goto out_unlock; 899 } 900 901 /* Input system HW workaround */ 902 atomisp_dma_burst_len_cfg(asd); 903 904 /* Invalidate caches. FIXME: should flush only necessary buffers */ 905 wbinvd(); 906 907 if (asd->params.css_update_params_needed) { 908 atomisp_apply_css_parameters(asd, &asd->params.css_param); 909 if (asd->params.css_param.update_flag.dz_config) 910 asd->params.config.dz_config = &asd->params.css_param.dz_config; 911 atomisp_css_update_isp_params(asd); 912 asd->params.css_update_params_needed = false; 913 memset(&asd->params.css_param.update_flag, 0, 914 sizeof(struct atomisp_parameters)); 915 } 916 asd->params.dvs_6axis = NULL; 917 918 ret = atomisp_css_start(asd); 919 if (ret) { 920 atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_QUEUED, true); 921 goto out_unlock; 922 } 923 924 spin_lock_irqsave(&isp->lock, irqflags); 925 asd->streaming = true; 926 spin_unlock_irqrestore(&isp->lock, irqflags); 927 atomic_set(&asd->sof_count, 0); 928 atomic_set(&asd->sequence, 0); 929 atomic_set(&asd->sequence_temp, 0); 930 931 asd->params.dis_proj_data_valid = false; 932 asd->latest_preview_exp_id = 0; 933 asd->postview_exp_id = 1; 934 asd->preview_exp_id = 1; 935 936 /* handle per_frame_setting parameter and buffers */ 937 atomisp_handle_parameter_and_buffer(pipe); 938 939 atomisp_qbuffers_to_css(asd); 940 941 atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, 942 atomisp_css_valid_sof(isp)); 943 atomisp_csi2_configure(asd); 944 945 if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_AUTO, false) < 0) 946 dev_dbg(isp->dev, "DFS auto mode failed!\n"); 947 948 /* Enable the CSI interface on ANN B0/K0 */ 949 if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << 950 ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) { 951 pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL, 952 isp->saved_regs.csi_control | MRFLD_PCI_CSI_CONTROL_CSI_READY); 953 } 954 955 /* stream on the sensor */ 956 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 957 video, s_stream, 1); 958 if (ret) { 959 dev_err(isp->dev, "Starting sensor stream failed: %d\n", ret); 960 spin_lock_irqsave(&isp->lock, irqflags); 961 asd->streaming = false; 962 spin_unlock_irqrestore(&isp->lock, irqflags); 963 ret = -EINVAL; 964 goto out_unlock; 965 } 966 967 out_unlock: 968 mutex_unlock(&isp->mutex); 969 return ret; 970 } 971 atomisp_stop_streaming(struct vb2_queue * vq)972 void atomisp_stop_streaming(struct vb2_queue *vq) 973 { 974 struct atomisp_video_pipe *pipe = vq_to_pipe(vq); 975 struct atomisp_sub_device *asd = pipe->asd; 976 struct atomisp_device *isp = asd->isp; 977 struct pci_dev *pdev = to_pci_dev(isp->dev); 978 unsigned long flags; 979 int ret; 980 981 dev_dbg(isp->dev, "Stop stream\n"); 982 983 mutex_lock(&isp->mutex); 984 /* 985 * There is no guarantee that the buffers queued to / owned by the ISP 986 * will properly be returned to the queue when stopping. Set a flag to 987 * avoid new buffers getting queued and then wait for all the current 988 * buffers to finish. 989 */ 990 pipe->stopping = true; 991 mutex_unlock(&isp->mutex); 992 /* wait max 1 second */ 993 ret = wait_event_timeout(pipe->vb_queue.done_wq, 994 atomisp_buffers_in_css(pipe) == 0, HZ); 995 mutex_lock(&isp->mutex); 996 pipe->stopping = false; 997 if (ret == 0) 998 dev_warn(isp->dev, "Warning timeout waiting for CSS to return buffers\n"); 999 1000 spin_lock_irqsave(&isp->lock, flags); 1001 asd->streaming = false; 1002 spin_unlock_irqrestore(&isp->lock, flags); 1003 1004 atomisp_clear_css_buffer_counters(asd); 1005 atomisp_css_irq_enable(isp, IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF, false); 1006 1007 atomisp_css_stop(asd, false); 1008 1009 atomisp_flush_video_pipe(pipe, VB2_BUF_STATE_ERROR, true); 1010 1011 atomisp_subdev_cleanup_pending_events(asd); 1012 1013 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, 1014 video, s_stream, 0); 1015 if (ret) 1016 dev_warn(isp->dev, "Stopping sensor stream failed: %d\n", ret); 1017 1018 /* Disable the CSI interface on ANN B0/K0 */ 1019 if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 << 1020 ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) { 1021 pci_write_config_word(pdev, MRFLD_PCI_CSI_CONTROL, 1022 isp->saved_regs.csi_control & ~MRFLD_PCI_CSI_CONTROL_CSI_READY); 1023 } 1024 1025 if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false)) 1026 dev_warn(isp->dev, "DFS failed.\n"); 1027 1028 /* 1029 * ISP work around, need to reset ISP to allow next stream on to work. 1030 * Streams have already been destroyed by atomisp_css_stop(). 1031 * Disable PUNIT/ISP acknowlede/handshake - SRSE=3 and then reset. 1032 */ 1033 pci_write_config_dword(pdev, PCI_I_CONTROL, 1034 isp->saved_regs.i_control | MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK); 1035 atomisp_reset(isp); 1036 1037 /* Streams were destroyed by atomisp_css_stop(), recreate them. */ 1038 ret = atomisp_create_pipes_stream(&isp->asd); 1039 if (ret) 1040 dev_warn(isp->dev, "Recreating streams failed: %d\n", ret); 1041 1042 media_pipeline_stop(&asd->video_out.vdev.entity.pads[0]); 1043 mutex_unlock(&isp->mutex); 1044 } 1045 1046 /* 1047 * To get the current value of a control. 1048 * applications initialize the id field of a struct v4l2_control and 1049 * call this ioctl with a pointer to this structure 1050 */ atomisp_g_ctrl(struct file * file,void * fh,struct v4l2_control * control)1051 static int atomisp_g_ctrl(struct file *file, void *fh, 1052 struct v4l2_control *control) 1053 { 1054 struct video_device *vdev = video_devdata(file); 1055 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1056 int i, ret = -EINVAL; 1057 1058 for (i = 0; i < ctrls_num; i++) { 1059 if (ci_v4l2_controls[i].id == control->id) { 1060 ret = 0; 1061 break; 1062 } 1063 } 1064 1065 if (ret) 1066 return ret; 1067 1068 switch (control->id) { 1069 case V4L2_CID_COLORFX: 1070 ret = atomisp_color_effect(asd, 0, &control->value); 1071 break; 1072 case V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION: 1073 ret = atomisp_bad_pixel(asd, 0, &control->value); 1074 break; 1075 case V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC: 1076 ret = atomisp_gdc_cac(asd, 0, &control->value); 1077 break; 1078 case V4L2_CID_ATOMISP_VIDEO_STABLIZATION: 1079 ret = atomisp_video_stable(asd, 0, &control->value); 1080 break; 1081 case V4L2_CID_ATOMISP_FIXED_PATTERN_NR: 1082 ret = atomisp_fixed_pattern(asd, 0, &control->value); 1083 break; 1084 case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION: 1085 ret = atomisp_false_color(asd, 0, &control->value); 1086 break; 1087 case V4L2_CID_ATOMISP_LOW_LIGHT: 1088 ret = atomisp_low_light(asd, 0, &control->value); 1089 break; 1090 default: 1091 ret = -EINVAL; 1092 break; 1093 } 1094 1095 return ret; 1096 } 1097 1098 /* 1099 * To change the value of a control. 1100 * applications initialize the id and value fields of a struct v4l2_control 1101 * and call this ioctl. 1102 */ atomisp_s_ctrl(struct file * file,void * fh,struct v4l2_control * control)1103 static int atomisp_s_ctrl(struct file *file, void *fh, 1104 struct v4l2_control *control) 1105 { 1106 struct video_device *vdev = video_devdata(file); 1107 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1108 int i, ret = -EINVAL; 1109 1110 for (i = 0; i < ctrls_num; i++) { 1111 if (ci_v4l2_controls[i].id == control->id) { 1112 ret = 0; 1113 break; 1114 } 1115 } 1116 1117 if (ret) 1118 return ret; 1119 1120 switch (control->id) { 1121 case V4L2_CID_COLORFX: 1122 ret = atomisp_color_effect(asd, 1, &control->value); 1123 break; 1124 case V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION: 1125 ret = atomisp_bad_pixel(asd, 1, &control->value); 1126 break; 1127 case V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC: 1128 ret = atomisp_gdc_cac(asd, 1, &control->value); 1129 break; 1130 case V4L2_CID_ATOMISP_VIDEO_STABLIZATION: 1131 ret = atomisp_video_stable(asd, 1, &control->value); 1132 break; 1133 case V4L2_CID_ATOMISP_FIXED_PATTERN_NR: 1134 ret = atomisp_fixed_pattern(asd, 1, &control->value); 1135 break; 1136 case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION: 1137 ret = atomisp_false_color(asd, 1, &control->value); 1138 break; 1139 case V4L2_CID_ATOMISP_LOW_LIGHT: 1140 ret = atomisp_low_light(asd, 1, &control->value); 1141 break; 1142 default: 1143 ret = -EINVAL; 1144 break; 1145 } 1146 return ret; 1147 } 1148 1149 /* 1150 * To query the attributes of a control. 1151 * applications set the id field of a struct v4l2_queryctrl and call the 1152 * this ioctl with a pointer to this structure. The driver fills 1153 * the rest of the structure. 1154 */ atomisp_queryctl(struct file * file,void * fh,struct v4l2_queryctrl * qc)1155 static int atomisp_queryctl(struct file *file, void *fh, 1156 struct v4l2_queryctrl *qc) 1157 { 1158 int i, ret = -EINVAL; 1159 1160 if (qc->id & V4L2_CTRL_FLAG_NEXT_CTRL) 1161 return ret; 1162 1163 for (i = 0; i < ctrls_num; i++) { 1164 if (ci_v4l2_controls[i].id == qc->id) { 1165 memcpy(qc, &ci_v4l2_controls[i], 1166 sizeof(struct v4l2_queryctrl)); 1167 qc->reserved[0] = 0; 1168 ret = 0; 1169 break; 1170 } 1171 } 1172 if (ret != 0) 1173 qc->flags = V4L2_CTRL_FLAG_DISABLED; 1174 1175 return ret; 1176 } 1177 atomisp_camera_g_ext_ctrls(struct file * file,void * fh,struct v4l2_ext_controls * c)1178 static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh, 1179 struct v4l2_ext_controls *c) 1180 { 1181 struct video_device *vdev = video_devdata(file); 1182 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1183 struct v4l2_control ctrl; 1184 int i; 1185 int ret = 0; 1186 1187 for (i = 0; i < c->count; i++) { 1188 ctrl.id = c->controls[i].id; 1189 ctrl.value = c->controls[i].value; 1190 switch (ctrl.id) { 1191 case V4L2_CID_ZOOM_ABSOLUTE: 1192 ret = atomisp_digital_zoom(asd, 0, &ctrl.value); 1193 break; 1194 default: 1195 ret = -EINVAL; 1196 } 1197 1198 if (ret) { 1199 c->error_idx = i; 1200 break; 1201 } 1202 c->controls[i].value = ctrl.value; 1203 } 1204 return ret; 1205 } 1206 1207 /* This ioctl allows the application to get multiple controls by class */ atomisp_g_ext_ctrls(struct file * file,void * fh,struct v4l2_ext_controls * c)1208 static int atomisp_g_ext_ctrls(struct file *file, void *fh, 1209 struct v4l2_ext_controls *c) 1210 { 1211 struct v4l2_control ctrl; 1212 int i, ret = 0; 1213 1214 /* 1215 * input_lock is not need for the Camera related IOCTLs 1216 * The input_lock downgrade the FPS of 3A 1217 */ 1218 ret = atomisp_camera_g_ext_ctrls(file, fh, c); 1219 if (ret != -EINVAL) 1220 return ret; 1221 1222 for (i = 0; i < c->count; i++) { 1223 ctrl.id = c->controls[i].id; 1224 ctrl.value = c->controls[i].value; 1225 ret = atomisp_g_ctrl(file, fh, &ctrl); 1226 c->controls[i].value = ctrl.value; 1227 if (ret) { 1228 c->error_idx = i; 1229 break; 1230 } 1231 } 1232 return ret; 1233 } 1234 atomisp_camera_s_ext_ctrls(struct file * file,void * fh,struct v4l2_ext_controls * c)1235 static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh, 1236 struct v4l2_ext_controls *c) 1237 { 1238 struct video_device *vdev = video_devdata(file); 1239 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1240 struct v4l2_control ctrl; 1241 int i; 1242 int ret = 0; 1243 1244 for (i = 0; i < c->count; i++) { 1245 struct v4l2_ctrl *ctr; 1246 1247 ctrl.id = c->controls[i].id; 1248 ctrl.value = c->controls[i].value; 1249 switch (ctrl.id) { 1250 case V4L2_CID_ZOOM_ABSOLUTE: 1251 ret = atomisp_digital_zoom(asd, 1, &ctrl.value); 1252 break; 1253 default: 1254 ctr = v4l2_ctrl_find(&asd->ctrl_handler, ctrl.id); 1255 if (ctr) 1256 ret = v4l2_ctrl_s_ctrl(ctr, ctrl.value); 1257 else 1258 ret = -EINVAL; 1259 } 1260 1261 if (ret) { 1262 c->error_idx = i; 1263 break; 1264 } 1265 c->controls[i].value = ctrl.value; 1266 } 1267 return ret; 1268 } 1269 1270 /* This ioctl allows the application to set multiple controls by class */ atomisp_s_ext_ctrls(struct file * file,void * fh,struct v4l2_ext_controls * c)1271 static int atomisp_s_ext_ctrls(struct file *file, void *fh, 1272 struct v4l2_ext_controls *c) 1273 { 1274 struct v4l2_control ctrl; 1275 int i, ret = 0; 1276 1277 /* 1278 * input_lock is not need for the Camera related IOCTLs 1279 * The input_lock downgrade the FPS of 3A 1280 */ 1281 ret = atomisp_camera_s_ext_ctrls(file, fh, c); 1282 if (ret != -EINVAL) 1283 return ret; 1284 1285 for (i = 0; i < c->count; i++) { 1286 ctrl.id = c->controls[i].id; 1287 ctrl.value = c->controls[i].value; 1288 ret = atomisp_s_ctrl(file, fh, &ctrl); 1289 c->controls[i].value = ctrl.value; 1290 if (ret) { 1291 c->error_idx = i; 1292 break; 1293 } 1294 } 1295 return ret; 1296 } 1297 1298 /* 1299 * vidioc_g/s_param are used to switch isp running mode 1300 */ atomisp_g_parm(struct file * file,void * fh,struct v4l2_streamparm * parm)1301 static int atomisp_g_parm(struct file *file, void *fh, 1302 struct v4l2_streamparm *parm) 1303 { 1304 struct video_device *vdev = video_devdata(file); 1305 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1306 struct atomisp_device *isp = video_get_drvdata(vdev); 1307 1308 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1309 dev_err(isp->dev, "unsupported v4l2 buf type\n"); 1310 return -EINVAL; 1311 } 1312 1313 parm->parm.capture.capturemode = asd->run_mode->val; 1314 1315 return 0; 1316 } 1317 atomisp_s_parm(struct file * file,void * fh,struct v4l2_streamparm * parm)1318 static int atomisp_s_parm(struct file *file, void *fh, 1319 struct v4l2_streamparm *parm) 1320 { 1321 struct video_device *vdev = video_devdata(file); 1322 struct atomisp_device *isp = video_get_drvdata(vdev); 1323 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1324 int mode; 1325 int rval; 1326 int fps; 1327 1328 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 1329 dev_err(isp->dev, "unsupported v4l2 buf type\n"); 1330 return -EINVAL; 1331 } 1332 1333 asd->high_speed_mode = false; 1334 switch (parm->parm.capture.capturemode) { 1335 case CI_MODE_NONE: { 1336 struct v4l2_subdev_frame_interval fi = {0}; 1337 1338 fi.interval = parm->parm.capture.timeperframe; 1339 1340 rval = v4l2_subdev_call_state_active(isp->inputs[asd->input_curr].camera, 1341 pad, set_frame_interval, &fi); 1342 if (!rval) 1343 parm->parm.capture.timeperframe = fi.interval; 1344 1345 if (fi.interval.numerator != 0) { 1346 fps = fi.interval.denominator / fi.interval.numerator; 1347 if (fps > 30) 1348 asd->high_speed_mode = true; 1349 } 1350 1351 return rval == -ENOIOCTLCMD ? 0 : rval; 1352 } 1353 case CI_MODE_VIDEO: 1354 mode = ATOMISP_RUN_MODE_VIDEO; 1355 break; 1356 case CI_MODE_STILL_CAPTURE: 1357 mode = ATOMISP_RUN_MODE_STILL_CAPTURE; 1358 break; 1359 case CI_MODE_PREVIEW: 1360 mode = ATOMISP_RUN_MODE_PREVIEW; 1361 break; 1362 default: 1363 return -EINVAL; 1364 } 1365 1366 rval = v4l2_ctrl_s_ctrl(asd->run_mode, mode); 1367 1368 return rval == -ENOIOCTLCMD ? 0 : rval; 1369 } 1370 atomisp_vidioc_default(struct file * file,void * fh,bool valid_prio,unsigned int cmd,void * arg)1371 static long atomisp_vidioc_default(struct file *file, void *fh, 1372 bool valid_prio, unsigned int cmd, void *arg) 1373 { 1374 struct video_device *vdev = video_devdata(file); 1375 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; 1376 int err; 1377 1378 switch (cmd) { 1379 case ATOMISP_IOC_G_XNR: 1380 err = atomisp_xnr(asd, 0, arg); 1381 break; 1382 1383 case ATOMISP_IOC_S_XNR: 1384 err = atomisp_xnr(asd, 1, arg); 1385 break; 1386 1387 case ATOMISP_IOC_G_NR: 1388 err = atomisp_nr(asd, 0, arg); 1389 break; 1390 1391 case ATOMISP_IOC_S_NR: 1392 err = atomisp_nr(asd, 1, arg); 1393 break; 1394 1395 case ATOMISP_IOC_G_TNR: 1396 err = atomisp_tnr(asd, 0, arg); 1397 break; 1398 1399 case ATOMISP_IOC_S_TNR: 1400 err = atomisp_tnr(asd, 1, arg); 1401 break; 1402 1403 case ATOMISP_IOC_G_BLACK_LEVEL_COMP: 1404 err = atomisp_black_level(asd, 0, arg); 1405 break; 1406 1407 case ATOMISP_IOC_S_BLACK_LEVEL_COMP: 1408 err = atomisp_black_level(asd, 1, arg); 1409 break; 1410 1411 case ATOMISP_IOC_G_EE: 1412 err = atomisp_ee(asd, 0, arg); 1413 break; 1414 1415 case ATOMISP_IOC_S_EE: 1416 err = atomisp_ee(asd, 1, arg); 1417 break; 1418 1419 case ATOMISP_IOC_G_DIS_STAT: 1420 err = atomisp_get_dis_stat(asd, arg); 1421 break; 1422 1423 case ATOMISP_IOC_G_DVS2_BQ_RESOLUTIONS: 1424 err = atomisp_get_dvs2_bq_resolutions(asd, arg); 1425 break; 1426 1427 case ATOMISP_IOC_S_DIS_COEFS: 1428 err = atomisp_css_cp_dvs2_coefs(asd, arg, 1429 &asd->params.css_param, true); 1430 if (!err && arg) 1431 asd->params.css_update_params_needed = true; 1432 break; 1433 1434 case ATOMISP_IOC_S_DIS_VECTOR: 1435 err = atomisp_cp_dvs_6axis_config(asd, arg, 1436 &asd->params.css_param, true); 1437 if (!err && arg) 1438 asd->params.css_update_params_needed = true; 1439 break; 1440 1441 case ATOMISP_IOC_G_ISP_PARM: 1442 err = atomisp_param(asd, 0, arg); 1443 break; 1444 1445 case ATOMISP_IOC_S_ISP_PARM: 1446 err = atomisp_param(asd, 1, arg); 1447 break; 1448 1449 case ATOMISP_IOC_G_3A_STAT: 1450 err = atomisp_3a_stat(asd, 0, arg); 1451 break; 1452 1453 case ATOMISP_IOC_G_ISP_GAMMA: 1454 err = atomisp_gamma(asd, 0, arg); 1455 break; 1456 1457 case ATOMISP_IOC_S_ISP_GAMMA: 1458 err = atomisp_gamma(asd, 1, arg); 1459 break; 1460 1461 case ATOMISP_IOC_G_ISP_GDC_TAB: 1462 err = atomisp_gdc_cac_table(asd, 0, arg); 1463 break; 1464 1465 case ATOMISP_IOC_S_ISP_GDC_TAB: 1466 err = atomisp_gdc_cac_table(asd, 1, arg); 1467 break; 1468 1469 case ATOMISP_IOC_G_ISP_MACC: 1470 err = atomisp_macc_table(asd, 0, arg); 1471 break; 1472 1473 case ATOMISP_IOC_S_ISP_MACC: 1474 err = atomisp_macc_table(asd, 1, arg); 1475 break; 1476 1477 case ATOMISP_IOC_G_ISP_BAD_PIXEL_DETECTION: 1478 err = atomisp_bad_pixel_param(asd, 0, arg); 1479 break; 1480 1481 case ATOMISP_IOC_S_ISP_BAD_PIXEL_DETECTION: 1482 err = atomisp_bad_pixel_param(asd, 1, arg); 1483 break; 1484 1485 case ATOMISP_IOC_G_ISP_FALSE_COLOR_CORRECTION: 1486 err = atomisp_false_color_param(asd, 0, arg); 1487 break; 1488 1489 case ATOMISP_IOC_S_ISP_FALSE_COLOR_CORRECTION: 1490 err = atomisp_false_color_param(asd, 1, arg); 1491 break; 1492 1493 case ATOMISP_IOC_G_ISP_CTC: 1494 err = atomisp_ctc(asd, 0, arg); 1495 break; 1496 1497 case ATOMISP_IOC_S_ISP_CTC: 1498 err = atomisp_ctc(asd, 1, arg); 1499 break; 1500 1501 case ATOMISP_IOC_G_ISP_WHITE_BALANCE: 1502 err = atomisp_white_balance_param(asd, 0, arg); 1503 break; 1504 1505 case ATOMISP_IOC_S_ISP_WHITE_BALANCE: 1506 err = atomisp_white_balance_param(asd, 1, arg); 1507 break; 1508 1509 case ATOMISP_IOC_G_3A_CONFIG: 1510 err = atomisp_3a_config_param(asd, 0, arg); 1511 break; 1512 1513 case ATOMISP_IOC_S_3A_CONFIG: 1514 err = atomisp_3a_config_param(asd, 1, arg); 1515 break; 1516 1517 case ATOMISP_IOC_S_ISP_FPN_TABLE: 1518 err = atomisp_fixed_pattern_table(asd, arg); 1519 break; 1520 1521 case ATOMISP_IOC_S_ISP_SHD_TAB: 1522 err = atomisp_set_shading_table(asd, arg); 1523 break; 1524 1525 case ATOMISP_IOC_G_ISP_GAMMA_CORRECTION: 1526 err = atomisp_gamma_correction(asd, 0, arg); 1527 break; 1528 1529 case ATOMISP_IOC_S_ISP_GAMMA_CORRECTION: 1530 err = atomisp_gamma_correction(asd, 1, arg); 1531 break; 1532 1533 case ATOMISP_IOC_S_PARAMETERS: 1534 err = atomisp_set_parameters(vdev, arg); 1535 break; 1536 1537 case ATOMISP_IOC_EXP_ID_UNLOCK: 1538 err = atomisp_exp_id_unlock(asd, arg); 1539 break; 1540 case ATOMISP_IOC_EXP_ID_CAPTURE: 1541 err = atomisp_exp_id_capture(asd, arg); 1542 break; 1543 case ATOMISP_IOC_S_ENABLE_DZ_CAPT_PIPE: 1544 err = atomisp_enable_dz_capt_pipe(asd, arg); 1545 break; 1546 case ATOMISP_IOC_G_FORMATS_CONFIG: 1547 err = atomisp_formats(asd, 0, arg); 1548 break; 1549 1550 case ATOMISP_IOC_S_FORMATS_CONFIG: 1551 err = atomisp_formats(asd, 1, arg); 1552 break; 1553 case ATOMISP_IOC_INJECT_A_FAKE_EVENT: 1554 err = atomisp_inject_a_fake_event(asd, arg); 1555 break; 1556 case ATOMISP_IOC_S_ARRAY_RESOLUTION: 1557 err = atomisp_set_array_res(asd, arg); 1558 break; 1559 default: 1560 err = -EINVAL; 1561 break; 1562 } 1563 1564 return err; 1565 } 1566 1567 const struct v4l2_ioctl_ops atomisp_ioctl_ops = { 1568 .vidioc_querycap = atomisp_querycap, 1569 .vidioc_enum_input = atomisp_enum_input, 1570 .vidioc_g_input = atomisp_g_input, 1571 .vidioc_s_input = atomisp_s_input, 1572 .vidioc_queryctrl = atomisp_queryctl, 1573 .vidioc_s_ctrl = atomisp_s_ctrl, 1574 .vidioc_g_ctrl = atomisp_g_ctrl, 1575 .vidioc_s_ext_ctrls = atomisp_s_ext_ctrls, 1576 .vidioc_g_ext_ctrls = atomisp_g_ext_ctrls, 1577 .vidioc_enum_framesizes = atomisp_enum_framesizes, 1578 .vidioc_enum_frameintervals = atomisp_enum_frameintervals, 1579 .vidioc_enum_fmt_vid_cap = atomisp_enum_fmt_cap, 1580 .vidioc_try_fmt_vid_cap = atomisp_try_fmt_cap, 1581 .vidioc_g_fmt_vid_cap = atomisp_g_fmt_cap, 1582 .vidioc_s_fmt_vid_cap = atomisp_s_fmt_cap, 1583 .vidioc_reqbufs = vb2_ioctl_reqbufs, 1584 .vidioc_querybuf = vb2_ioctl_querybuf, 1585 .vidioc_qbuf = atomisp_qbuf_wrapper, 1586 .vidioc_dqbuf = atomisp_dqbuf_wrapper, 1587 .vidioc_expbuf = vb2_ioctl_expbuf, 1588 .vidioc_streamon = vb2_ioctl_streamon, 1589 .vidioc_streamoff = vb2_ioctl_streamoff, 1590 .vidioc_default = atomisp_vidioc_default, 1591 .vidioc_s_parm = atomisp_s_parm, 1592 .vidioc_g_parm = atomisp_g_parm, 1593 }; 1594