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