1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <linux/delay.h>
25#include <linux/pci.h>
26
27#include <asm/intel-mid.h>
28
29#include <media/v4l2-ioctl.h>
30#include <media/v4l2-event.h>
31#include <media/videobuf-vmalloc.h>
32
33#include "atomisp_acc.h"
34#include "atomisp_cmd.h"
35#include "atomisp_common.h"
36#include "atomisp_fops.h"
37#include "atomisp_internal.h"
38#include "atomisp_ioctl.h"
39#include "atomisp-regs.h"
40#include "atomisp_compat.h"
41
42#include "sh_css_hrt.h"
43
44#include "gp_device.h"
45#include "device_access.h"
46#include "irq.h"
47
48#include "hrt/hive_isp_css_mm_hrt.h"
49
50
51static const char *DRIVER = "atomisp";
52static const char *CARD = "ATOM ISP";
53static const char *BUS_INFO = "PCI-3";
54static const u32 VERSION = DRIVER_VERSION;
55
56
57
58
59
60static struct v4l2_queryctrl ci_v4l2_controls[] = {
61 {
62 .id = V4L2_CID_AUTO_WHITE_BALANCE,
63 .type = V4L2_CTRL_TYPE_BOOLEAN,
64 .name = "Automatic White Balance",
65 .minimum = 0,
66 .maximum = 1,
67 .step = 1,
68 .default_value = 0,
69 },
70 {
71 .id = V4L2_CID_RED_BALANCE,
72 .type = V4L2_CTRL_TYPE_INTEGER,
73 .name = "Red Balance",
74 .minimum = 0x00,
75 .maximum = 0xff,
76 .step = 1,
77 .default_value = 0x00,
78 },
79 {
80 .id = V4L2_CID_BLUE_BALANCE,
81 .type = V4L2_CTRL_TYPE_INTEGER,
82 .name = "Blue Balance",
83 .minimum = 0x00,
84 .maximum = 0xff,
85 .step = 1,
86 .default_value = 0x00,
87 },
88 {
89 .id = V4L2_CID_GAMMA,
90 .type = V4L2_CTRL_TYPE_INTEGER,
91 .name = "Gamma",
92 .minimum = 0x00,
93 .maximum = 0xff,
94 .step = 1,
95 .default_value = 0x00,
96 },
97 {
98 .id = V4L2_CID_POWER_LINE_FREQUENCY,
99 .type = V4L2_CTRL_TYPE_MENU,
100 .name = "Light frequency filter",
101 .minimum = 1,
102 .maximum = 2,
103 .step = 1,
104 .default_value = 1,
105 },
106 {
107 .id = V4L2_CID_COLORFX,
108 .type = V4L2_CTRL_TYPE_INTEGER,
109 .name = "Image Color Effect",
110 .minimum = 0,
111 .maximum = 9,
112 .step = 1,
113 .default_value = 0,
114 },
115 {
116 .id = V4L2_CID_COLORFX_CBCR,
117 .type = V4L2_CTRL_TYPE_INTEGER,
118 .name = "Image Color Effect CbCr",
119 .minimum = 0,
120 .maximum = 0xffff,
121 .step = 1,
122 .default_value = 0,
123 },
124 {
125 .id = V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION,
126 .type = V4L2_CTRL_TYPE_INTEGER,
127 .name = "Bad Pixel Correction",
128 .minimum = 0,
129 .maximum = 1,
130 .step = 1,
131 .default_value = 0,
132 },
133 {
134 .id = V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC,
135 .type = V4L2_CTRL_TYPE_INTEGER,
136 .name = "GDC/CAC",
137 .minimum = 0,
138 .maximum = 1,
139 .step = 1,
140 .default_value = 0,
141 },
142 {
143 .id = V4L2_CID_ATOMISP_VIDEO_STABLIZATION,
144 .type = V4L2_CTRL_TYPE_INTEGER,
145 .name = "Video Stablization",
146 .minimum = 0,
147 .maximum = 1,
148 .step = 1,
149 .default_value = 0,
150 },
151 {
152 .id = V4L2_CID_ATOMISP_FIXED_PATTERN_NR,
153 .type = V4L2_CTRL_TYPE_INTEGER,
154 .name = "Fixed Pattern Noise Reduction",
155 .minimum = 0,
156 .maximum = 1,
157 .step = 1,
158 .default_value = 0,
159 },
160 {
161 .id = V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION,
162 .type = V4L2_CTRL_TYPE_INTEGER,
163 .name = "False Color Correction",
164 .minimum = 0,
165 .maximum = 1,
166 .step = 1,
167 .default_value = 0,
168 },
169 {
170 .id = V4L2_CID_REQUEST_FLASH,
171 .type = V4L2_CTRL_TYPE_INTEGER,
172 .name = "Request flash frames",
173 .minimum = 0,
174 .maximum = 10,
175 .step = 1,
176 .default_value = 1,
177 },
178 {
179 .id = V4L2_CID_ATOMISP_LOW_LIGHT,
180 .type = V4L2_CTRL_TYPE_BOOLEAN,
181 .name = "Low light mode",
182 .minimum = 0,
183 .maximum = 1,
184 .step = 1,
185 .default_value = 1,
186 },
187 {
188 .id = V4L2_CID_BIN_FACTOR_HORZ,
189 .type = V4L2_CTRL_TYPE_INTEGER,
190 .name = "Horizontal binning factor",
191 .minimum = 0,
192 .maximum = 10,
193 .step = 1,
194 .default_value = 0,
195 },
196 {
197 .id = V4L2_CID_BIN_FACTOR_VERT,
198 .type = V4L2_CTRL_TYPE_INTEGER,
199 .name = "Vertical binning factor",
200 .minimum = 0,
201 .maximum = 10,
202 .step = 1,
203 .default_value = 0,
204 },
205 {
206 .id = V4L2_CID_2A_STATUS,
207 .type = V4L2_CTRL_TYPE_BITMASK,
208 .name = "AE and AWB status",
209 .minimum = 0,
210 .maximum = V4L2_2A_STATUS_AE_READY | V4L2_2A_STATUS_AWB_READY,
211 .step = 1,
212 .default_value = 0,
213 },
214 {
215 .id = V4L2_CID_EXPOSURE,
216 .type = V4L2_CTRL_TYPE_INTEGER,
217 .name = "exposure",
218 .minimum = -4,
219 .maximum = 4,
220 .step = 1,
221 .default_value = 0,
222 },
223 {
224 .id = V4L2_CID_EXPOSURE_ZONE_NUM,
225 .type = V4L2_CTRL_TYPE_INTEGER,
226 .name = "one-time exposure zone number",
227 .minimum = 0x0,
228 .maximum = 0xffff,
229 .step = 1,
230 .default_value = 0,
231 },
232 {
233 .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY,
234 .type = V4L2_CTRL_TYPE_INTEGER,
235 .name = "Exposure auto priority",
236 .minimum = V4L2_EXPOSURE_AUTO,
237 .maximum = V4L2_EXPOSURE_APERTURE_PRIORITY,
238 .step = 1,
239 .default_value = V4L2_EXPOSURE_AUTO,
240 },
241 {
242 .id = V4L2_CID_SCENE_MODE,
243 .type = V4L2_CTRL_TYPE_INTEGER,
244 .name = "scene mode",
245 .minimum = 0,
246 .maximum = 13,
247 .step = 1,
248 .default_value = 0,
249 },
250 {
251 .id = V4L2_CID_ISO_SENSITIVITY,
252 .type = V4L2_CTRL_TYPE_INTEGER,
253 .name = "iso",
254 .minimum = -4,
255 .maximum = 4,
256 .step = 1,
257 .default_value = 0,
258 },
259 {
260 .id = V4L2_CID_ISO_SENSITIVITY_AUTO,
261 .type = V4L2_CTRL_TYPE_INTEGER,
262 .name = "iso mode",
263 .minimum = V4L2_ISO_SENSITIVITY_MANUAL,
264 .maximum = V4L2_ISO_SENSITIVITY_AUTO,
265 .step = 1,
266 .default_value = V4L2_ISO_SENSITIVITY_AUTO,
267 },
268 {
269 .id = V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE,
270 .type = V4L2_CTRL_TYPE_INTEGER,
271 .name = "white balance",
272 .minimum = 0,
273 .maximum = 9,
274 .step = 1,
275 .default_value = 0,
276 },
277 {
278 .id = V4L2_CID_EXPOSURE_METERING,
279 .type = V4L2_CTRL_TYPE_MENU,
280 .name = "metering",
281 .minimum = 0,
282 .maximum = 3,
283 .step = 1,
284 .default_value = 1,
285 },
286 {
287 .id = V4L2_CID_3A_LOCK,
288 .type = V4L2_CTRL_TYPE_BITMASK,
289 .name = "3a lock",
290 .minimum = 0,
291 .maximum = V4L2_LOCK_EXPOSURE | V4L2_LOCK_WHITE_BALANCE
292 | V4L2_LOCK_FOCUS,
293 .step = 1,
294 .default_value = 0,
295 },
296 {
297 .id = V4L2_CID_TEST_PATTERN,
298 .type = V4L2_CTRL_TYPE_INTEGER,
299 .name = "Test Pattern",
300 .minimum = 0,
301 .maximum = 0xffff,
302 .step = 1,
303 .default_value = 0,
304 },
305 {
306 .id = V4L2_CID_TEST_PATTERN_COLOR_R,
307 .type = V4L2_CTRL_TYPE_INTEGER,
308 .name = "Test Pattern Solid Color R",
309 .minimum = INT_MIN,
310 .maximum = INT_MAX,
311 .step = 1,
312 .default_value = 0,
313 },
314 {
315 .id = V4L2_CID_TEST_PATTERN_COLOR_GR,
316 .type = V4L2_CTRL_TYPE_INTEGER,
317 .name = "Test Pattern Solid Color GR",
318 .minimum = INT_MIN,
319 .maximum = INT_MAX,
320 .step = 1,
321 .default_value = 0,
322 },
323 {
324 .id = V4L2_CID_TEST_PATTERN_COLOR_GB,
325 .type = V4L2_CTRL_TYPE_INTEGER,
326 .name = "Test Pattern Solid Color GB",
327 .minimum = INT_MIN,
328 .maximum = INT_MAX,
329 .step = 1,
330 .default_value = 0,
331 },
332 {
333 .id = V4L2_CID_TEST_PATTERN_COLOR_B,
334 .type = V4L2_CTRL_TYPE_INTEGER,
335 .name = "Test Pattern Solid Color B",
336 .minimum = INT_MIN,
337 .maximum = INT_MAX,
338 .step = 1,
339 .default_value = 0,
340 },
341};
342static const u32 ctrls_num = ARRAY_SIZE(ci_v4l2_controls);
343
344
345
346
347const struct atomisp_format_bridge atomisp_output_fmts[] = {
348 {
349 .pixelformat = V4L2_PIX_FMT_YUV420,
350 .depth = 12,
351 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV420,
352 .sh_fmt = CSS_FRAME_FORMAT_YUV420,
353 .description = "YUV420, planar",
354 .planar = true
355 }, {
356 .pixelformat = V4L2_PIX_FMT_YVU420,
357 .depth = 12,
358 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YVU420,
359 .sh_fmt = CSS_FRAME_FORMAT_YV12,
360 .description = "YVU420, planar",
361 .planar = true
362 }, {
363 .pixelformat = V4L2_PIX_FMT_YUV422P,
364 .depth = 16,
365 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV422P,
366 .sh_fmt = CSS_FRAME_FORMAT_YUV422,
367 .description = "YUV422, planar",
368 .planar = true
369 }, {
370 .pixelformat = V4L2_PIX_FMT_YUV444,
371 .depth = 24,
372 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUV444,
373 .sh_fmt = CSS_FRAME_FORMAT_YUV444,
374 .description = "YUV444"
375 }, {
376 .pixelformat = V4L2_PIX_FMT_NV12,
377 .depth = 12,
378 .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV12,
379 .sh_fmt = CSS_FRAME_FORMAT_NV12,
380 .description = "NV12, Y-plane, CbCr interleaved",
381 .planar = true
382 }, {
383 .pixelformat = V4L2_PIX_FMT_NV21,
384 .depth = 12,
385 .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV21,
386 .sh_fmt = CSS_FRAME_FORMAT_NV21,
387 .description = "NV21, Y-plane, CbCr interleaved",
388 .planar = true
389 }, {
390 .pixelformat = V4L2_PIX_FMT_NV16,
391 .depth = 16,
392 .mbus_code = V4L2_MBUS_FMT_CUSTOM_NV16,
393 .sh_fmt = CSS_FRAME_FORMAT_NV16,
394 .description = "NV16, Y-plane, CbCr interleaved",
395 .planar = true
396 }, {
397 .pixelformat = V4L2_PIX_FMT_YUYV,
398 .depth = 16,
399 .mbus_code = V4L2_MBUS_FMT_CUSTOM_YUYV,
400 .sh_fmt = CSS_FRAME_FORMAT_YUYV,
401 .description = "YUYV, interleaved"
402 }, {
403 .pixelformat = V4L2_PIX_FMT_UYVY,
404 .depth = 16,
405 .mbus_code = MEDIA_BUS_FMT_UYVY8_1X16,
406 .sh_fmt = CSS_FRAME_FORMAT_UYVY,
407 .description = "UYVY, interleaved"
408 }, {
409 .pixelformat = V4L2_PIX_FMT_UYVY,
410 .depth = 16,
411 .mbus_code = MEDIA_BUS_FMT_UYVY8_2X8,
412 .sh_fmt = CSS_FRAME_FORMAT_UYVY,
413 .description = "UYVY, interleaved"
414 }, {
415 .pixelformat = V4L2_PIX_FMT_SBGGR16,
416 .depth = 16,
417 .mbus_code = V4L2_MBUS_FMT_CUSTOM_SBGGR16,
418 .sh_fmt = CSS_FRAME_FORMAT_RAW,
419 .description = "Bayer 16"
420 }, {
421 .pixelformat = V4L2_PIX_FMT_SBGGR8,
422 .depth = 8,
423 .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8,
424 .sh_fmt = CSS_FRAME_FORMAT_RAW,
425 .description = "Bayer 8"
426 }, {
427 .pixelformat = V4L2_PIX_FMT_SGBRG8,
428 .depth = 8,
429 .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8,
430 .sh_fmt = CSS_FRAME_FORMAT_RAW,
431 .description = "Bayer 8"
432 }, {
433 .pixelformat = V4L2_PIX_FMT_SGRBG8,
434 .depth = 8,
435 .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8,
436 .sh_fmt = CSS_FRAME_FORMAT_RAW,
437 .description = "Bayer 8"
438 }, {
439 .pixelformat = V4L2_PIX_FMT_SRGGB8,
440 .depth = 8,
441 .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8,
442 .sh_fmt = CSS_FRAME_FORMAT_RAW,
443 .description = "Bayer 8"
444 }, {
445 .pixelformat = V4L2_PIX_FMT_SBGGR10,
446 .depth = 16,
447 .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10,
448 .sh_fmt = CSS_FRAME_FORMAT_RAW,
449 .description = "Bayer 10"
450 }, {
451 .pixelformat = V4L2_PIX_FMT_SGBRG10,
452 .depth = 16,
453 .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10,
454 .sh_fmt = CSS_FRAME_FORMAT_RAW,
455 .description = "Bayer 10"
456 }, {
457 .pixelformat = V4L2_PIX_FMT_SGRBG10,
458 .depth = 16,
459 .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10,
460 .sh_fmt = CSS_FRAME_FORMAT_RAW,
461 .description = "Bayer 10"
462 }, {
463 .pixelformat = V4L2_PIX_FMT_SRGGB10,
464 .depth = 16,
465 .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10,
466 .sh_fmt = CSS_FRAME_FORMAT_RAW,
467 .description = "Bayer 10"
468 }, {
469 .pixelformat = V4L2_PIX_FMT_SBGGR12,
470 .depth = 16,
471 .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12,
472 .sh_fmt = CSS_FRAME_FORMAT_RAW,
473 .description = "Bayer 12"
474 }, {
475 .pixelformat = V4L2_PIX_FMT_SGBRG12,
476 .depth = 16,
477 .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12,
478 .sh_fmt = CSS_FRAME_FORMAT_RAW,
479 .description = "Bayer 12"
480 }, {
481 .pixelformat = V4L2_PIX_FMT_SGRBG12,
482 .depth = 16,
483 .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12,
484 .sh_fmt = CSS_FRAME_FORMAT_RAW,
485 .description = "Bayer 12"
486 }, {
487 .pixelformat = V4L2_PIX_FMT_SRGGB12,
488 .depth = 16,
489 .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12,
490 .sh_fmt = CSS_FRAME_FORMAT_RAW,
491 .description = "Bayer 12"
492 }, {
493 .pixelformat = V4L2_PIX_FMT_RGB32,
494 .depth = 32,
495 .mbus_code = V4L2_MBUS_FMT_CUSTOM_RGB32,
496 .sh_fmt = CSS_FRAME_FORMAT_RGBA888,
497 .description = "32 RGB 8-8-8-8"
498 }, {
499 .pixelformat = V4L2_PIX_FMT_RGB565,
500 .depth = 16,
501 .mbus_code = MEDIA_BUS_FMT_BGR565_2X8_LE,
502 .sh_fmt = CSS_FRAME_FORMAT_RGB565,
503 .description = "16 RGB 5-6-5"
504 }, {
505 .pixelformat = V4L2_PIX_FMT_JPEG,
506 .depth = 8,
507 .mbus_code = MEDIA_BUS_FMT_JPEG_1X8,
508 .sh_fmt = CSS_FRAME_FORMAT_BINARY_8,
509 .description = "JPEG"
510 }, {
511
512 .pixelformat = V4L2_PIX_FMT_CUSTOM_M10MO_RAW,
513 .depth = 8,
514 .mbus_code = V4L2_MBUS_FMT_CUSTOM_M10MO_RAW,
515 .sh_fmt = CSS_FRAME_FORMAT_BINARY_8,
516 .description = "Custom RAW for M10MO"
517 },
518};
519
520const struct atomisp_format_bridge *atomisp_get_format_bridge(
521 unsigned int pixelformat)
522{
523 unsigned int i;
524
525 for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
526 if (atomisp_output_fmts[i].pixelformat == pixelformat)
527 return &atomisp_output_fmts[i];
528 }
529
530 return NULL;
531}
532
533const struct atomisp_format_bridge *atomisp_get_format_bridge_from_mbus(
534 u32 mbus_code)
535{
536 unsigned int i;
537
538 for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
539 if (mbus_code == atomisp_output_fmts[i].mbus_code)
540 return &atomisp_output_fmts[i];
541 }
542
543 return NULL;
544}
545
546
547
548
549
550
551
552static int atomisp_querycap(struct file *file, void *fh,
553 struct v4l2_capability *cap)
554{
555 memset(cap, 0, sizeof(struct v4l2_capability));
556
557 WARN_ON(sizeof(DRIVER) > sizeof(cap->driver) ||
558 sizeof(CARD) > sizeof(cap->card) ||
559 sizeof(BUS_INFO) > sizeof(cap->bus_info));
560
561 strncpy(cap->driver, DRIVER, sizeof(cap->driver) - 1);
562 strncpy(cap->card, CARD, sizeof(cap->card) - 1);
563 strncpy(cap->bus_info, BUS_INFO, sizeof(cap->card) - 1);
564
565 cap->version = VERSION;
566
567 cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
568 V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OUTPUT;
569 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
570 return 0;
571}
572
573
574
575
576static int atomisp_enum_input(struct file *file, void *fh,
577 struct v4l2_input *input)
578{
579 struct video_device *vdev = video_devdata(file);
580 struct atomisp_device *isp = video_get_drvdata(vdev);
581 int index = input->index;
582
583 if (index >= isp->input_cnt)
584 return -EINVAL;
585
586 if (!isp->inputs[index].camera)
587 return -EINVAL;
588
589 memset(input, 0, sizeof(struct v4l2_input));
590 strncpy(input->name, isp->inputs[index].camera->name,
591 sizeof(input->name) - 1);
592
593
594
595
596
597
598
599#ifndef ISP2401
600 if (isp->inputs[index].motor &&
601 strlen(isp->inputs[index].motor->name) > 0) {
602#else
603 if (isp->motor &&
604 strlen(isp->motor->name) > 0) {
605#endif
606 const int cur_len = strlen(input->name);
607 const int max_size = sizeof(input->name) - cur_len - 1;
608
609 if (max_size > 1) {
610 input->name[cur_len] = '+';
611 strncpy(&input->name[cur_len + 1],
612#ifndef ISP2401
613 isp->inputs[index].motor->name, max_size - 1);
614#else
615 isp->motor->name, max_size - 1);
616#endif
617 }
618 }
619
620 input->type = V4L2_INPUT_TYPE_CAMERA;
621 input->index = index;
622 input->reserved[0] = isp->inputs[index].type;
623 input->reserved[1] = isp->inputs[index].port;
624
625 return 0;
626}
627
628static unsigned int atomisp_subdev_streaming_count(
629 struct atomisp_sub_device *asd)
630{
631 return asd->video_out_preview.capq.streaming
632 + asd->video_out_capture.capq.streaming
633 + asd->video_out_video_capture.capq.streaming
634 + asd->video_out_vf.capq.streaming
635 + asd->video_in.capq.streaming;
636}
637
638unsigned int atomisp_streaming_count(struct atomisp_device *isp)
639{
640 unsigned int i, sum;
641
642 for (i = 0, sum = 0; i < isp->num_of_streams; i++)
643 sum += isp->asd[i].streaming ==
644 ATOMISP_DEVICE_STREAMING_ENABLED;
645
646 return sum;
647}
648
649unsigned int atomisp_is_acc_enabled(struct atomisp_device *isp)
650{
651 unsigned int i;
652
653 for (i = 0; i < isp->num_of_streams; i++)
654 if (isp->asd[i].acc.pipeline)
655 return 1;
656
657 return 0;
658}
659
660
661
662static int atomisp_g_input(struct file *file, void *fh, unsigned int *input)
663{
664 struct video_device *vdev = video_devdata(file);
665 struct atomisp_device *isp = video_get_drvdata(vdev);
666 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
667
668 rt_mutex_lock(&isp->mutex);
669 *input = asd->input_curr;
670 rt_mutex_unlock(&isp->mutex);
671
672 return 0;
673}
674
675
676
677static int atomisp_s_input(struct file *file, void *fh, unsigned int input)
678{
679 struct video_device *vdev = video_devdata(file);
680 struct atomisp_device *isp = video_get_drvdata(vdev);
681 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
682 struct v4l2_subdev *camera = NULL;
683 int ret;
684
685 rt_mutex_lock(&isp->mutex);
686 if (input >= ATOM_ISP_MAX_INPUTS || input >= isp->input_cnt) {
687 dev_dbg(isp->dev, "input_cnt: %d\n", isp->input_cnt);
688 ret = -EINVAL;
689 goto error;
690 }
691
692
693
694
695
696
697 if (isp->inputs[input].asd != NULL && isp->inputs[input].asd != asd) {
698 dev_err(isp->dev,
699 "%s, camera is already used by stream: %d\n", __func__,
700 isp->inputs[input].asd->index);
701 ret = -EBUSY;
702 goto error;
703 }
704
705 camera = isp->inputs[input].camera;
706 if (!camera) {
707 dev_err(isp->dev, "%s, no camera\n", __func__);
708 ret = -EINVAL;
709 goto error;
710 }
711
712 if (atomisp_subdev_streaming_count(asd)) {
713 dev_err(isp->dev,
714 "ISP is still streaming, stop first\n");
715 ret = -EINVAL;
716 goto error;
717 }
718
719
720 if (isp->inputs[asd->input_curr].asd == asd &&
721 asd->input_curr != input) {
722 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
723 core, s_power, 0);
724 if (ret)
725 dev_warn(isp->dev,
726 "Failed to power-off sensor\n");
727
728 isp->inputs[asd->input_curr].asd = NULL;
729 }
730
731
732 ret = v4l2_subdev_call(isp->inputs[input].camera, core, s_power, 1);
733 if (ret) {
734 dev_err(isp->dev, "Failed to power-on sensor\n");
735 goto error;
736 }
737
738
739
740
741 atomisp_update_run_mode(asd);
742
743
744 ret = v4l2_subdev_call(isp->inputs[input].camera, video, s_routing,
745 0, isp->inputs[input].sensor_index, 0);
746 if (ret && (ret != -ENOIOCTLCMD)) {
747 dev_err(isp->dev, "Failed to select sensor\n");
748 goto error;
749 }
750
751#ifndef ISP2401
752 if (!isp->sw_contex.file_input && isp->inputs[input].motor)
753 ret = v4l2_subdev_call(isp->inputs[input].motor, core,
754 init, 1);
755#else
756 if (isp->motor)
757 ret = v4l2_subdev_call(isp->motor, core, s_power, 1);
758
759 if (!isp->sw_contex.file_input && isp->motor)
760 ret = v4l2_subdev_call(isp->motor, core, init, 1);
761#endif
762
763 asd->input_curr = input;
764
765 isp->inputs[input].asd = asd;
766 rt_mutex_unlock(&isp->mutex);
767
768 return 0;
769
770error:
771 rt_mutex_unlock(&isp->mutex);
772
773 return ret;
774}
775
776static int atomisp_enum_fmt_cap(struct file *file, void *fh,
777 struct v4l2_fmtdesc *f)
778{
779 struct video_device *vdev = video_devdata(file);
780 struct atomisp_device *isp = video_get_drvdata(vdev);
781 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
782 struct v4l2_subdev_mbus_code_enum code = { 0 };
783 unsigned int i, fi = 0;
784 int rval;
785
786 rt_mutex_lock(&isp->mutex);
787 rval = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, pad,
788 enum_mbus_code, NULL, &code);
789 if (rval == -ENOIOCTLCMD) {
790 dev_warn(isp->dev, "enum_mbus_code pad op not supported. Please fix your sensor driver!\n");
791
792
793 }
794 rt_mutex_unlock(&isp->mutex);
795
796 if (rval)
797 return rval;
798
799 for (i = 0; i < ARRAY_SIZE(atomisp_output_fmts); i++) {
800 const struct atomisp_format_bridge *format =
801 &atomisp_output_fmts[i];
802
803
804
805
806
807 if (format->sh_fmt == CSS_FRAME_FORMAT_RAW
808 && format->mbus_code != code.code)
809 continue;
810
811
812 if (fi < f->index) {
813 fi++;
814 continue;
815 }
816
817 strlcpy(f->description, format->description,
818 sizeof(f->description));
819 f->pixelformat = format->pixelformat;
820 return 0;
821 }
822
823 return -EINVAL;
824}
825
826static int atomisp_g_fmt_cap(struct file *file, void *fh,
827 struct v4l2_format *f)
828{
829 struct video_device *vdev = video_devdata(file);
830 struct atomisp_device *isp = video_get_drvdata(vdev);
831
832 int ret;
833
834 rt_mutex_lock(&isp->mutex);
835 ret = atomisp_get_fmt(vdev, f);
836 rt_mutex_unlock(&isp->mutex);
837 return ret;
838}
839
840static int atomisp_g_fmt_file(struct file *file, void *fh,
841 struct v4l2_format *f)
842{
843 struct video_device *vdev = video_devdata(file);
844 struct atomisp_device *isp = video_get_drvdata(vdev);
845 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
846
847 rt_mutex_lock(&isp->mutex);
848 f->fmt.pix = pipe->pix;
849 rt_mutex_unlock(&isp->mutex);
850
851 return 0;
852}
853
854
855static int atomisp_try_fmt_cap(struct file *file, void *fh,
856 struct v4l2_format *f)
857{
858 struct video_device *vdev = video_devdata(file);
859 struct atomisp_device *isp = video_get_drvdata(vdev);
860 int ret;
861
862 rt_mutex_lock(&isp->mutex);
863 ret = atomisp_try_fmt(vdev, f, NULL);
864 rt_mutex_unlock(&isp->mutex);
865 return ret;
866}
867
868static int atomisp_s_fmt_cap(struct file *file, void *fh,
869 struct v4l2_format *f)
870{
871 struct video_device *vdev = video_devdata(file);
872 struct atomisp_device *isp = video_get_drvdata(vdev);
873 int ret;
874
875 rt_mutex_lock(&isp->mutex);
876 if (isp->isp_fatal_error) {
877 ret = -EIO;
878 rt_mutex_unlock(&isp->mutex);
879 return ret;
880 }
881 ret = atomisp_set_fmt(vdev, f);
882 rt_mutex_unlock(&isp->mutex);
883 return ret;
884}
885
886static int atomisp_s_fmt_file(struct file *file, void *fh,
887 struct v4l2_format *f)
888{
889 struct video_device *vdev = video_devdata(file);
890 struct atomisp_device *isp = video_get_drvdata(vdev);
891 int ret;
892
893 rt_mutex_lock(&isp->mutex);
894 ret = atomisp_set_fmt_file(vdev, f);
895 rt_mutex_unlock(&isp->mutex);
896 return ret;
897}
898
899
900
901
902void atomisp_videobuf_free_buf(struct videobuf_buffer *vb)
903{
904 struct videobuf_vmalloc_memory *vm_mem;
905
906 if (vb == NULL)
907 return;
908
909 vm_mem = vb->priv;
910 if (vm_mem && vm_mem->vaddr) {
911 atomisp_css_frame_free(vm_mem->vaddr);
912 vm_mem->vaddr = NULL;
913 }
914}
915
916
917
918
919static void atomisp_videobuf_free_queue(struct videobuf_queue *q)
920{
921 int i;
922
923 for (i = 0; i < VIDEO_MAX_FRAME; i++) {
924 atomisp_videobuf_free_buf(q->bufs[i]);
925 kfree(q->bufs[i]);
926 q->bufs[i] = NULL;
927 }
928}
929
930int atomisp_alloc_css_stat_bufs(struct atomisp_sub_device *asd,
931 uint16_t stream_id)
932{
933 struct atomisp_device *isp = asd->isp;
934 struct atomisp_s3a_buf *s3a_buf = NULL, *_s3a_buf;
935 struct atomisp_dis_buf *dis_buf = NULL, *_dis_buf;
936 struct atomisp_metadata_buf *md_buf = NULL, *_md_buf;
937 int count;
938 struct atomisp_css_dvs_grid_info *dvs_grid_info =
939 atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
940 unsigned int i;
941
942 if (list_empty(&asd->s3a_stats) &&
943 asd->params.curr_grid_info.s3a_grid.enable) {
944 count = ATOMISP_CSS_Q_DEPTH +
945 ATOMISP_S3A_BUF_QUEUE_DEPTH_FOR_HAL;
946 dev_dbg(isp->dev, "allocating %d 3a buffers\n", count);
947 while (count--) {
948 s3a_buf = kzalloc(sizeof(struct atomisp_s3a_buf), GFP_KERNEL);
949 if (!s3a_buf) {
950 dev_err(isp->dev, "s3a stat buf alloc failed\n");
951 goto error;
952 }
953
954 if (atomisp_css_allocate_stat_buffers(
955 asd, stream_id, s3a_buf, NULL, NULL)) {
956 kfree(s3a_buf);
957 goto error;
958 }
959
960 list_add_tail(&s3a_buf->list, &asd->s3a_stats);
961 }
962 }
963
964 if (list_empty(&asd->dis_stats) && dvs_grid_info &&
965 dvs_grid_info->enable) {
966 count = ATOMISP_CSS_Q_DEPTH + 1;
967 dev_dbg(isp->dev, "allocating %d dis buffers\n", count);
968 while (count--) {
969 dis_buf = kzalloc(sizeof(struct atomisp_dis_buf), GFP_KERNEL);
970 if (!dis_buf) {
971 dev_err(isp->dev, "dis stat buf alloc failed\n");
972 kfree(s3a_buf);
973 goto error;
974 }
975 if (atomisp_css_allocate_stat_buffers(
976 asd, stream_id, NULL, dis_buf, NULL)) {
977 kfree(dis_buf);
978 goto error;
979 }
980
981 list_add_tail(&dis_buf->list, &asd->dis_stats);
982 }
983 }
984
985 for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
986 if (list_empty(&asd->metadata[i]) &&
987 list_empty(&asd->metadata_ready[i]) &&
988 list_empty(&asd->metadata_in_css[i])) {
989 count = ATOMISP_CSS_Q_DEPTH +
990 ATOMISP_METADATA_QUEUE_DEPTH_FOR_HAL;
991 dev_dbg(isp->dev, "allocating %d metadata buffers for type %d\n",
992 count, i);
993 while (count--) {
994 md_buf = kzalloc(sizeof(struct atomisp_metadata_buf),
995 GFP_KERNEL);
996 if (!md_buf) {
997 dev_err(isp->dev, "metadata buf alloc failed\n");
998 goto error;
999 }
1000
1001 if (atomisp_css_allocate_stat_buffers(
1002 asd, stream_id, NULL, NULL, md_buf)) {
1003 kfree(md_buf);
1004 goto error;
1005 }
1006 list_add_tail(&md_buf->list, &asd->metadata[i]);
1007 }
1008 }
1009 }
1010 return 0;
1011
1012error:
1013 dev_err(isp->dev, "failed to allocate statistics buffers\n");
1014
1015 list_for_each_entry_safe(dis_buf, _dis_buf, &asd->dis_stats, list) {
1016 atomisp_css_free_dis_buffer(dis_buf);
1017 list_del(&dis_buf->list);
1018 kfree(dis_buf);
1019 }
1020
1021 list_for_each_entry_safe(s3a_buf, _s3a_buf, &asd->s3a_stats, list) {
1022 atomisp_css_free_3a_buffer(s3a_buf);
1023 list_del(&s3a_buf->list);
1024 kfree(s3a_buf);
1025 }
1026
1027 for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
1028 list_for_each_entry_safe(md_buf, _md_buf, &asd->metadata[i],
1029 list) {
1030 atomisp_css_free_metadata_buffer(md_buf);
1031 list_del(&md_buf->list);
1032 kfree(md_buf);
1033 }
1034 }
1035 return -ENOMEM;
1036}
1037
1038
1039
1040
1041int __atomisp_reqbufs(struct file *file, void *fh,
1042 struct v4l2_requestbuffers *req)
1043{
1044 struct video_device *vdev = video_devdata(file);
1045 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1046 struct atomisp_sub_device *asd = pipe->asd;
1047 struct atomisp_css_frame_info frame_info;
1048 struct atomisp_css_frame *frame;
1049 struct videobuf_vmalloc_memory *vm_mem;
1050 uint16_t source_pad = atomisp_subdev_source_pad(vdev);
1051 uint16_t stream_id = atomisp_source_pad_to_stream_id(asd, source_pad);
1052 int ret = 0, i = 0;
1053
1054 if (req->count == 0) {
1055 mutex_lock(&pipe->capq.vb_lock);
1056 if (!list_empty(&pipe->capq.stream))
1057 videobuf_queue_cancel(&pipe->capq);
1058
1059 atomisp_videobuf_free_queue(&pipe->capq);
1060 mutex_unlock(&pipe->capq.vb_lock);
1061
1062 memset(pipe->frame_request_config_id, 0,
1063 VIDEO_MAX_FRAME * sizeof(unsigned int));
1064 memset(pipe->frame_params, 0,
1065 VIDEO_MAX_FRAME *
1066 sizeof(struct atomisp_css_params_with_list *));
1067 return 0;
1068 }
1069
1070 ret = videobuf_reqbufs(&pipe->capq, req);
1071 if (ret)
1072 return ret;
1073
1074 atomisp_alloc_css_stat_bufs(asd, stream_id);
1075
1076
1077
1078
1079
1080 if (req->memory == V4L2_MEMORY_USERPTR)
1081 return 0;
1082
1083 ret = atomisp_get_css_frame_info(asd, source_pad, &frame_info);
1084 if (ret)
1085 return ret;
1086
1087
1088
1089
1090
1091 for (i = 0; i < req->count; i++) {
1092 if (atomisp_css_frame_allocate_from_info(&frame, &frame_info))
1093 goto error;
1094 vm_mem = pipe->capq.bufs[i]->priv;
1095 vm_mem->vaddr = frame;
1096 }
1097
1098 return ret;
1099
1100error:
1101 while (i--) {
1102 vm_mem = pipe->capq.bufs[i]->priv;
1103 atomisp_css_frame_free(vm_mem->vaddr);
1104 }
1105
1106 if (asd->vf_frame)
1107 atomisp_css_frame_free(asd->vf_frame);
1108
1109 return -ENOMEM;
1110}
1111
1112int atomisp_reqbufs(struct file *file, void *fh,
1113 struct v4l2_requestbuffers *req)
1114{
1115 struct video_device *vdev = video_devdata(file);
1116 struct atomisp_device *isp = video_get_drvdata(vdev);
1117 int ret;
1118
1119 rt_mutex_lock(&isp->mutex);
1120 ret = __atomisp_reqbufs(file, fh, req);
1121 rt_mutex_unlock(&isp->mutex);
1122
1123 return ret;
1124}
1125
1126static int atomisp_reqbufs_file(struct file *file, void *fh,
1127 struct v4l2_requestbuffers *req)
1128{
1129 struct video_device *vdev = video_devdata(file);
1130 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1131
1132 if (req->count == 0) {
1133 mutex_lock(&pipe->outq.vb_lock);
1134 atomisp_videobuf_free_queue(&pipe->outq);
1135 mutex_unlock(&pipe->outq.vb_lock);
1136 return 0;
1137 }
1138
1139 return videobuf_reqbufs(&pipe->outq, req);
1140}
1141
1142
1143static int atomisp_querybuf(struct file *file, void *fh,
1144 struct v4l2_buffer *buf)
1145{
1146 struct video_device *vdev = video_devdata(file);
1147 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1148
1149 return videobuf_querybuf(&pipe->capq, buf);
1150}
1151
1152static int atomisp_querybuf_file(struct file *file, void *fh,
1153 struct v4l2_buffer *buf)
1154{
1155 struct video_device *vdev = video_devdata(file);
1156 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1157
1158 return videobuf_querybuf(&pipe->outq, buf);
1159}
1160
1161
1162
1163
1164
1165static int atomisp_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1166{
1167 static const int NOFLUSH_FLAGS = V4L2_BUF_FLAG_NO_CACHE_INVALIDATE |
1168 V4L2_BUF_FLAG_NO_CACHE_CLEAN;
1169 struct video_device *vdev = video_devdata(file);
1170 struct atomisp_device *isp = video_get_drvdata(vdev);
1171 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1172 struct atomisp_sub_device *asd = pipe->asd;
1173 struct videobuf_buffer *vb;
1174 struct videobuf_vmalloc_memory *vm_mem;
1175 struct atomisp_css_frame_info frame_info;
1176 struct atomisp_css_frame *handle = NULL;
1177 u32 length;
1178 u32 pgnr;
1179 int ret = 0;
1180
1181 rt_mutex_lock(&isp->mutex);
1182 if (isp->isp_fatal_error) {
1183 ret = -EIO;
1184 goto error;
1185 }
1186
1187 if (asd->streaming == ATOMISP_DEVICE_STREAMING_STOPPING) {
1188 dev_err(isp->dev, "%s: reject, as ISP at stopping.\n",
1189 __func__);
1190 ret = -EIO;
1191 goto error;
1192 }
1193
1194 if (!buf || buf->index >= VIDEO_MAX_FRAME ||
1195 !pipe->capq.bufs[buf->index]) {
1196 dev_err(isp->dev, "Invalid index for qbuf.\n");
1197 ret = -EINVAL;
1198 goto error;
1199 }
1200
1201
1202
1203
1204
1205 if (buf->memory == V4L2_MEMORY_USERPTR) {
1206 struct hrt_userbuffer_attr attributes;
1207 vb = pipe->capq.bufs[buf->index];
1208 vm_mem = vb->priv;
1209 if (!vm_mem) {
1210 ret = -EINVAL;
1211 goto error;
1212 }
1213
1214 length = vb->bsize;
1215 pgnr = (length + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
1216
1217 if (vb->baddr == buf->m.userptr && vm_mem->vaddr)
1218 goto done;
1219
1220 if (atomisp_get_css_frame_info(asd,
1221 atomisp_subdev_source_pad(vdev), &frame_info)) {
1222 ret = -EIO;
1223 goto error;
1224 }
1225
1226 attributes.pgnr = pgnr;
1227#ifdef CONFIG_ION
1228#ifndef ISP2401
1229 attributes.type = buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_ION
1230 ? HRT_USR_ION : HRT_USR_PTR;
1231#else
1232 if (buf->reserved & ATOMISP_BUFFER_TYPE_IS_ION) {
1233 attributes.type = HRT_USR_ION;
1234 if (asd->ion_dev_fd->val != ION_FD_UNSET) {
1235 dev_dbg(isp->dev, "ION buffer queued, share_fd=%lddev_fd=%d.\n",
1236 buf->m.userptr, asd->ion_dev_fd->val);
1237
1238
1239
1240
1241
1242 if ((buf->m.userptr &
1243 (ATOMISP_ION_DEVICE_FD_MASK)) != 0) {
1244 dev_err(isp->dev,
1245 "Error: v4l2 buffer fd:0X%0lX > 0XFFFF.\n",
1246 buf->m.userptr);
1247 ret = -EINVAL;
1248 goto error;
1249 }
1250 buf->m.userptr |= asd->ion_dev_fd->val <<
1251 ATOMISP_ION_DEVICE_FD_OFFSET;
1252 } else {
1253 dev_err(isp->dev, "v4l2 buffer type is ION, \
1254 but no dev fd set from userspace.\n");
1255 ret = -EINVAL;
1256 goto error;
1257 }
1258 } else {
1259 attributes.type = HRT_USR_PTR;
1260 }
1261#endif
1262#else
1263 attributes.type = HRT_USR_PTR;
1264#endif
1265 ret = atomisp_css_frame_map(&handle, &frame_info,
1266 (void *)buf->m.userptr,
1267 0, &attributes);
1268 if (ret) {
1269 dev_err(isp->dev, "Failed to map user buffer\n");
1270 goto error;
1271 }
1272
1273 if (vm_mem->vaddr) {
1274 mutex_lock(&pipe->capq.vb_lock);
1275 atomisp_css_frame_free(vm_mem->vaddr);
1276 vm_mem->vaddr = NULL;
1277 vb->state = VIDEOBUF_NEEDS_INIT;
1278 mutex_unlock(&pipe->capq.vb_lock);
1279 }
1280
1281 vm_mem->vaddr = handle;
1282
1283 buf->flags &= ~V4L2_BUF_FLAG_MAPPED;
1284 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1285 buf->flags &= ~V4L2_BUF_FLAG_DONE;
1286 } else if (buf->memory == V4L2_MEMORY_MMAP) {
1287 buf->flags |= V4L2_BUF_FLAG_MAPPED;
1288 buf->flags |= V4L2_BUF_FLAG_QUEUED;
1289 buf->flags &= ~V4L2_BUF_FLAG_DONE;
1290 }
1291
1292done:
1293 if (!((buf->flags & NOFLUSH_FLAGS) == NOFLUSH_FLAGS))
1294 wbinvd();
1295
1296 if (!atomisp_is_vf_pipe(pipe) &&
1297 (buf->reserved2 & ATOMISP_BUFFER_HAS_PER_FRAME_SETTING)) {
1298
1299 pipe->frame_request_config_id[buf->index] = buf->reserved2 &
1300 ~ATOMISP_BUFFER_HAS_PER_FRAME_SETTING;
1301 dev_dbg(isp->dev, "This buffer requires per_frame setting which has isp_config_id %d\n",
1302 pipe->frame_request_config_id[buf->index]);
1303 } else {
1304 pipe->frame_request_config_id[buf->index] = 0;
1305 }
1306
1307 pipe->frame_params[buf->index] = NULL;
1308
1309 rt_mutex_unlock(&isp->mutex);
1310
1311 ret = videobuf_qbuf(&pipe->capq, buf);
1312 rt_mutex_lock(&isp->mutex);
1313 if (ret)
1314 goto error;
1315
1316
1317 if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) {
1318 if (!list_empty(&pipe->buffers_waiting_for_param)) {
1319 atomisp_handle_parameter_and_buffer(pipe);
1320 } else {
1321 atomisp_qbuffers_to_css(asd);
1322
1323#ifndef ISP2401
1324 if (!atomisp_is_wdt_running(asd) && atomisp_buffers_queued(asd))
1325 atomisp_wdt_start(asd);
1326#else
1327 if (!atomisp_is_wdt_running(pipe) &&
1328 atomisp_buffers_queued_pipe(pipe))
1329 atomisp_wdt_start(pipe);
1330#endif
1331 }
1332 }
1333
1334
1335
1336
1337
1338
1339
1340
1341 if (asd->continuous_mode->val &&
1342 atomisp_subdev_source_pad(vdev)
1343 == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE &&
1344 pipe->capq.streaming &&
1345 !asd->enable_raw_buffer_lock->val &&
1346 asd->params.offline_parm.num_captures == 1) {
1347#ifndef ISP2401
1348 asd->pending_capture_request++;
1349 dev_dbg(isp->dev, "Add one pending capture request.\n");
1350#else
1351 if (asd->re_trigger_capture) {
1352 ret = atomisp_css_offline_capture_configure(asd,
1353 asd->params.offline_parm.num_captures,
1354 asd->params.offline_parm.skip_frames,
1355 asd->params.offline_parm.offset);
1356 asd->re_trigger_capture = false;
1357 dev_dbg(isp->dev, "%s Trigger capture again ret=%d\n",
1358 __func__, ret);
1359
1360 } else {
1361 asd->pending_capture_request++;
1362 asd->re_trigger_capture = false;
1363 dev_dbg(isp->dev, "Add one pending capture request.\n");
1364 }
1365#endif
1366 }
1367 rt_mutex_unlock(&isp->mutex);
1368
1369 dev_dbg(isp->dev, "qbuf buffer %d (%s) for asd%d\n", buf->index,
1370 vdev->name, asd->index);
1371
1372 return ret;
1373
1374error:
1375 rt_mutex_unlock(&isp->mutex);
1376 return ret;
1377}
1378
1379static int atomisp_qbuf_file(struct file *file, void *fh,
1380 struct v4l2_buffer *buf)
1381{
1382 struct video_device *vdev = video_devdata(file);
1383 struct atomisp_device *isp = video_get_drvdata(vdev);
1384 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1385 int ret;
1386
1387 rt_mutex_lock(&isp->mutex);
1388 if (isp->isp_fatal_error) {
1389 ret = -EIO;
1390 goto error;
1391 }
1392
1393 if (!buf || buf->index >= VIDEO_MAX_FRAME ||
1394 !pipe->outq.bufs[buf->index]) {
1395 dev_err(isp->dev, "Invalid index for qbuf.\n");
1396 ret = -EINVAL;
1397 goto error;
1398 }
1399
1400 if (buf->memory != V4L2_MEMORY_MMAP) {
1401 dev_err(isp->dev, "Unsupported memory method\n");
1402 ret = -EINVAL;
1403 goto error;
1404 }
1405
1406 if (buf->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1407 dev_err(isp->dev, "Unsupported buffer type\n");
1408 ret = -EINVAL;
1409 goto error;
1410 }
1411 rt_mutex_unlock(&isp->mutex);
1412
1413 return videobuf_qbuf(&pipe->outq, buf);
1414
1415error:
1416 rt_mutex_unlock(&isp->mutex);
1417
1418 return ret;
1419}
1420
1421static int __get_frame_exp_id(struct atomisp_video_pipe *pipe,
1422 struct v4l2_buffer *buf)
1423{
1424 struct videobuf_vmalloc_memory *vm_mem;
1425 struct atomisp_css_frame *handle;
1426 int i;
1427
1428 for (i = 0; pipe->capq.bufs[i]; i++) {
1429 vm_mem = pipe->capq.bufs[i]->priv;
1430 handle = vm_mem->vaddr;
1431 if (buf->index == pipe->capq.bufs[i]->i && handle)
1432 return handle->exp_id;
1433 }
1434 return -EINVAL;
1435}
1436
1437
1438
1439
1440
1441static int atomisp_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1442{
1443 struct video_device *vdev = video_devdata(file);
1444 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1445 struct atomisp_sub_device *asd = pipe->asd;
1446 struct atomisp_device *isp = video_get_drvdata(vdev);
1447 int ret = 0;
1448
1449 rt_mutex_lock(&isp->mutex);
1450
1451 if (isp->isp_fatal_error) {
1452 rt_mutex_unlock(&isp->mutex);
1453 return -EIO;
1454 }
1455
1456 if (asd->streaming == ATOMISP_DEVICE_STREAMING_STOPPING) {
1457 rt_mutex_unlock(&isp->mutex);
1458 dev_err(isp->dev, "%s: reject, as ISP at stopping.\n",
1459 __func__);
1460 return -EIO;
1461 }
1462
1463 rt_mutex_unlock(&isp->mutex);
1464
1465 ret = videobuf_dqbuf(&pipe->capq, buf, file->f_flags & O_NONBLOCK);
1466 if (ret) {
1467 dev_dbg(isp->dev, "<%s: %d\n", __func__, ret);
1468 return ret;
1469 }
1470 rt_mutex_lock(&isp->mutex);
1471 buf->bytesused = pipe->pix.sizeimage;
1472 buf->reserved = asd->frame_status[buf->index];
1473
1474
1475
1476
1477
1478
1479
1480 buf->reserved &= 0x0000ffff;
1481 if (!(buf->flags & V4L2_BUF_FLAG_ERROR))
1482 buf->reserved |= __get_frame_exp_id(pipe, buf) << 16;
1483 buf->reserved2 = pipe->frame_config_id[buf->index];
1484 rt_mutex_unlock(&isp->mutex);
1485
1486 dev_dbg(isp->dev, "dqbuf buffer %d (%s) for asd%d with exp_id %d, isp_config_id %d\n",
1487 buf->index, vdev->name, asd->index, buf->reserved >> 16,
1488 buf->reserved2);
1489 return 0;
1490}
1491
1492enum atomisp_css_pipe_id atomisp_get_css_pipe_id(struct atomisp_sub_device *asd)
1493{
1494 if (ATOMISP_USE_YUVPP(asd))
1495 return CSS_PIPE_ID_YUVPP;
1496
1497 if (asd->continuous_mode->val) {
1498 if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)
1499 return CSS_PIPE_ID_VIDEO;
1500 else
1501 return CSS_PIPE_ID_PREVIEW;
1502 }
1503
1504
1505
1506
1507
1508 if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER)
1509 return CSS_PIPE_ID_VIDEO;
1510
1511
1512
1513
1514
1515
1516 if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT)
1517 return CSS_PIPE_ID_CAPTURE;
1518
1519 switch (asd->run_mode->val) {
1520 case ATOMISP_RUN_MODE_PREVIEW:
1521 return CSS_PIPE_ID_PREVIEW;
1522 case ATOMISP_RUN_MODE_VIDEO:
1523 return CSS_PIPE_ID_VIDEO;
1524 case ATOMISP_RUN_MODE_STILL_CAPTURE:
1525
1526 default:
1527 return CSS_PIPE_ID_CAPTURE;
1528 }
1529}
1530
1531static unsigned int atomisp_sensor_start_stream(struct atomisp_sub_device *asd)
1532{
1533 struct atomisp_device *isp = asd->isp;
1534
1535 if (isp->inputs[asd->input_curr].camera_caps->
1536 sensor[asd->sensor_curr].stream_num > 1) {
1537 if (asd->high_speed_mode)
1538 return 1;
1539 else
1540 return 2;
1541 }
1542
1543 if (asd->vfpp->val != ATOMISP_VFPP_ENABLE ||
1544 asd->copy_mode)
1545 return 1;
1546
1547 if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO ||
1548 (asd->run_mode->val == ATOMISP_RUN_MODE_STILL_CAPTURE &&
1549 !atomisp_is_mbuscode_raw(
1550 asd->fmt[
1551 asd->capture_pad].fmt.code) &&
1552 !asd->continuous_mode->val))
1553 return 2;
1554 else
1555 return 1;
1556}
1557
1558int atomisp_stream_on_master_slave_sensor(struct atomisp_device *isp,
1559 bool isp_timeout)
1560{
1561 unsigned int master = -1, slave = -1, delay_slave = 0;
1562 int i, ret;
1563
1564
1565
1566
1567
1568 for (i = 0; i < isp->num_of_streams; i++) {
1569 int sensor_index = isp->asd[i].input_curr;
1570 if (isp->inputs[sensor_index].camera_caps->
1571 sensor[isp->asd[i].sensor_curr].is_slave)
1572 slave = sensor_index;
1573 else
1574 master = sensor_index;
1575 }
1576
1577 if (master == -1 || slave == -1) {
1578 master = ATOMISP_DEPTH_DEFAULT_MASTER_SENSOR;
1579 slave = ATOMISP_DEPTH_DEFAULT_SLAVE_SENSOR;
1580 dev_warn(isp->dev,
1581 "depth mode use default master=%s.slave=%s.\n",
1582 isp->inputs[master].camera->name,
1583 isp->inputs[slave].camera->name);
1584 }
1585
1586 ret = v4l2_subdev_call(isp->inputs[master].camera, core,
1587 ioctl, ATOMISP_IOC_G_DEPTH_SYNC_COMP,
1588 &delay_slave);
1589 if (ret)
1590 dev_warn(isp->dev,
1591 "get depth sensor %s compensation delay failed.\n",
1592 isp->inputs[master].camera->name);
1593
1594 ret = v4l2_subdev_call(isp->inputs[master].camera,
1595 video, s_stream, 1);
1596 if (ret) {
1597 dev_err(isp->dev, "depth mode master sensor %s stream-on failed.\n",
1598 isp->inputs[master].camera->name);
1599 return -EINVAL;
1600 }
1601
1602 if (delay_slave != 0)
1603 udelay(delay_slave);
1604
1605 ret = v4l2_subdev_call(isp->inputs[slave].camera,
1606 video, s_stream, 1);
1607 if (ret) {
1608 dev_err(isp->dev, "depth mode slave sensor %s stream-on failed.\n",
1609 isp->inputs[slave].camera->name);
1610 v4l2_subdev_call(isp->inputs[master].camera, video, s_stream, 0);
1611
1612 return -EINVAL;
1613 }
1614
1615 return 0;
1616}
1617
1618
1619#ifndef ISP2401
1620void __wdt_on_master_slave_sensor(struct atomisp_device *isp, unsigned int wdt_duration)
1621#else
1622void __wdt_on_master_slave_sensor(struct atomisp_video_pipe *pipe,
1623 unsigned int wdt_duration, bool enable)
1624#endif
1625{
1626#ifndef ISP2401
1627 if (atomisp_buffers_queued(&isp->asd[0]))
1628 atomisp_wdt_refresh(&isp->asd[0], wdt_duration);
1629 if (atomisp_buffers_queued(&isp->asd[1]))
1630 atomisp_wdt_refresh(&isp->asd[1], wdt_duration);
1631#else
1632 static struct atomisp_video_pipe *pipe0;
1633
1634 if (enable) {
1635 if (atomisp_buffers_queued_pipe(pipe0))
1636 atomisp_wdt_refresh_pipe(pipe0, wdt_duration);
1637 if (atomisp_buffers_queued_pipe(pipe))
1638 atomisp_wdt_refresh_pipe(pipe, wdt_duration);
1639 } else {
1640 pipe0 = pipe;
1641 }
1642#endif
1643}
1644
1645static void atomisp_pause_buffer_event(struct atomisp_device *isp)
1646{
1647 struct v4l2_event event = {0};
1648 int i;
1649
1650 event.type = V4L2_EVENT_ATOMISP_PAUSE_BUFFER;
1651
1652 for (i = 0; i < isp->num_of_streams; i++) {
1653 int sensor_index = isp->asd[i].input_curr;
1654 if (isp->inputs[sensor_index].camera_caps->
1655 sensor[isp->asd[i].sensor_curr].is_slave) {
1656 v4l2_event_queue(isp->asd[i].subdev.devnode, &event);
1657 break;
1658 }
1659 }
1660}
1661
1662
1663
1664
1665
1666static void atomisp_dma_burst_len_cfg(struct atomisp_sub_device *asd)
1667{
1668
1669 struct v4l2_mbus_framefmt *sink;
1670 sink = atomisp_subdev_get_ffmt(&asd->subdev, NULL,
1671 V4L2_SUBDEV_FORMAT_ACTIVE,
1672 ATOMISP_SUBDEV_PAD_SINK);
1673
1674 if (sink->width * sink->height >= 4096*3072)
1675 atomisp_store_uint32(DMA_BURST_SIZE_REG, 0x7F);
1676 else
1677 atomisp_store_uint32(DMA_BURST_SIZE_REG, 0x00);
1678}
1679
1680
1681
1682
1683static int atomisp_streamon(struct file *file, void *fh,
1684 enum v4l2_buf_type type)
1685{
1686 struct video_device *vdev = video_devdata(file);
1687 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1688 struct atomisp_sub_device *asd = pipe->asd;
1689 struct atomisp_device *isp = video_get_drvdata(vdev);
1690 enum atomisp_css_pipe_id css_pipe_id;
1691 unsigned int sensor_start_stream;
1692 unsigned int wdt_duration = ATOMISP_ISP_TIMEOUT_DURATION;
1693 int ret = 0;
1694 unsigned long irqflags;
1695
1696 dev_dbg(isp->dev, "Start stream on pad %d for asd%d\n",
1697 atomisp_subdev_source_pad(vdev), asd->index);
1698
1699 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1700 dev_dbg(isp->dev, "unsupported v4l2 buf type\n");
1701 return -EINVAL;
1702 }
1703
1704 rt_mutex_lock(&isp->mutex);
1705 if (isp->isp_fatal_error) {
1706 ret = -EIO;
1707 goto out;
1708 }
1709
1710 if (asd->streaming == ATOMISP_DEVICE_STREAMING_STOPPING) {
1711 ret = -EBUSY;
1712 goto out;
1713 }
1714
1715 if (pipe->capq.streaming)
1716 goto out;
1717
1718
1719 atomisp_dma_burst_len_cfg(asd);
1720
1721
1722
1723
1724
1725 sensor_start_stream = atomisp_sensor_start_stream(asd);
1726
1727 spin_lock_irqsave(&pipe->irq_lock, irqflags);
1728 if (list_empty(&(pipe->capq.stream))) {
1729 spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
1730 dev_dbg(isp->dev, "no buffer in the queue\n");
1731 ret = -EINVAL;
1732 goto out;
1733 }
1734 spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
1735
1736 ret = videobuf_streamon(&pipe->capq);
1737 if (ret)
1738 goto out;
1739
1740
1741 asd->pending_capture_request = 0;
1742#ifdef ISP2401
1743 asd->re_trigger_capture = false;
1744#endif
1745
1746 if ((atomisp_subdev_streaming_count(asd) > sensor_start_stream) &&
1747 (!isp->inputs[asd->input_curr].camera_caps->multi_stream_ctrl)) {
1748
1749 if (asd->continuous_mode->val &&
1750 atomisp_subdev_source_pad(vdev)
1751 == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) {
1752 if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO)
1753 dev_dbg(isp->dev, "SDV last video raw buffer id: %u\n",
1754 asd->latest_preview_exp_id);
1755 else
1756 dev_dbg(isp->dev, "ZSL last preview raw buffer id: %u\n",
1757 asd->latest_preview_exp_id);
1758
1759 if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) {
1760 flush_work(&asd->delayed_init_work);
1761 rt_mutex_unlock(&isp->mutex);
1762 if (wait_for_completion_interruptible(
1763 &asd->init_done) != 0)
1764 return -ERESTARTSYS;
1765 rt_mutex_lock(&isp->mutex);
1766 }
1767
1768
1769 atomisp_handle_parameter_and_buffer(pipe);
1770
1771
1772
1773
1774
1775
1776 atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_MAX, false);
1777
1778
1779
1780
1781
1782 if (!asd->enable_raw_buffer_lock->val) {
1783 ret = atomisp_css_offline_capture_configure(asd,
1784 asd->params.offline_parm.num_captures,
1785 asd->params.offline_parm.skip_frames,
1786 asd->params.offline_parm.offset);
1787 if (ret) {
1788 ret = -EINVAL;
1789 goto out;
1790 }
1791 if (asd->depth_mode->val)
1792 atomisp_pause_buffer_event(isp);
1793 }
1794 }
1795 atomisp_qbuffers_to_css(asd);
1796 goto out;
1797 }
1798
1799 if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) {
1800 atomisp_qbuffers_to_css(asd);
1801 goto start_sensor;
1802 }
1803
1804 css_pipe_id = atomisp_get_css_pipe_id(asd);
1805
1806 ret = atomisp_acc_load_extensions(asd);
1807 if (ret < 0) {
1808 dev_err(isp->dev, "acc extension failed to load\n");
1809 goto out;
1810 }
1811
1812 if (asd->params.css_update_params_needed) {
1813 atomisp_apply_css_parameters(asd, &asd->params.css_param);
1814 if (asd->params.css_param.update_flag.dz_config)
1815 atomisp_css_set_dz_config(asd,
1816 &asd->params.css_param.dz_config);
1817 atomisp_css_update_isp_params(asd);
1818 asd->params.css_update_params_needed = false;
1819 memset(&asd->params.css_param.update_flag, 0,
1820 sizeof(struct atomisp_parameters));
1821 }
1822 asd->params.dvs_6axis = NULL;
1823
1824 ret = atomisp_css_start(asd, css_pipe_id, false);
1825 if (ret)
1826 goto out;
1827
1828 asd->streaming = ATOMISP_DEVICE_STREAMING_ENABLED;
1829 atomic_set(&asd->sof_count, -1);
1830 atomic_set(&asd->sequence, -1);
1831 atomic_set(&asd->sequence_temp, -1);
1832 if (isp->sw_contex.file_input)
1833 wdt_duration = ATOMISP_ISP_FILE_TIMEOUT_DURATION;
1834
1835 asd->params.dis_proj_data_valid = false;
1836 asd->latest_preview_exp_id = 0;
1837 asd->postview_exp_id = 1;
1838 asd->preview_exp_id = 1;
1839
1840
1841 atomisp_handle_parameter_and_buffer(pipe);
1842
1843 atomisp_qbuffers_to_css(asd);
1844
1845
1846 if (atomisp_subdev_streaming_count(asd) < sensor_start_stream)
1847 goto out;
1848
1849start_sensor:
1850 if (isp->flash) {
1851 asd->params.num_flash_frames = 0;
1852 asd->params.flash_state = ATOMISP_FLASH_IDLE;
1853 atomisp_setup_flash(asd);
1854 }
1855
1856 if (!isp->sw_contex.file_input) {
1857 atomisp_css_irq_enable(isp, CSS_IRQ_INFO_CSS_RECEIVER_SOF,
1858 atomisp_css_valid_sof(isp));
1859 atomisp_csi2_configure(asd);
1860
1861
1862
1863
1864 if (atomisp_streaming_count(isp) > 1) {
1865 if (atomisp_freq_scaling(isp,
1866 ATOMISP_DFS_MODE_MAX, false) < 0)
1867 dev_dbg(isp->dev, "dfs failed!\n");
1868 } else {
1869 if (atomisp_freq_scaling(isp,
1870 ATOMISP_DFS_MODE_AUTO, false) < 0)
1871 dev_dbg(isp->dev, "dfs failed!\n");
1872 }
1873 } else {
1874 if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_MAX, false) < 0)
1875 dev_dbg(isp->dev, "dfs failed!\n");
1876 }
1877
1878 if (asd->depth_mode->val && atomisp_streaming_count(isp) ==
1879 ATOMISP_DEPTH_SENSOR_STREAMON_COUNT) {
1880 ret = atomisp_stream_on_master_slave_sensor(isp, false);
1881 if (ret) {
1882 dev_err(isp->dev, "master slave sensor stream on failed!\n");
1883 goto out;
1884 }
1885#ifndef ISP2401
1886 __wdt_on_master_slave_sensor(isp, wdt_duration);
1887#else
1888 __wdt_on_master_slave_sensor(pipe, wdt_duration, true);
1889#endif
1890 goto start_delay_wq;
1891 } else if (asd->depth_mode->val && (atomisp_streaming_count(isp) <
1892 ATOMISP_DEPTH_SENSOR_STREAMON_COUNT)) {
1893#ifdef ISP2401
1894 __wdt_on_master_slave_sensor(pipe, wdt_duration, false);
1895#endif
1896 goto start_delay_wq;
1897 }
1898
1899
1900 if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
1901 ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) {
1902 pci_write_config_word(isp->pdev, MRFLD_PCI_CSI_CONTROL,
1903 isp->saved_regs.csi_control |
1904 MRFLD_PCI_CSI_CONTROL_CSI_READY);
1905 }
1906
1907
1908 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
1909 video, s_stream, 1);
1910 if (ret) {
1911 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
1912 ret = -EINVAL;
1913 goto out;
1914 }
1915
1916#ifndef ISP2401
1917 if (atomisp_buffers_queued(asd))
1918 atomisp_wdt_refresh(asd, wdt_duration);
1919#else
1920 if (atomisp_buffers_queued_pipe(pipe))
1921 atomisp_wdt_refresh_pipe(pipe, wdt_duration);
1922#endif
1923
1924start_delay_wq:
1925 if (asd->continuous_mode->val) {
1926 struct v4l2_mbus_framefmt *sink;
1927
1928 sink = atomisp_subdev_get_ffmt(&asd->subdev, NULL,
1929 V4L2_SUBDEV_FORMAT_ACTIVE,
1930 ATOMISP_SUBDEV_PAD_SINK);
1931
1932 reinit_completion(&asd->init_done);
1933 asd->delayed_init = ATOMISP_DELAYED_INIT_QUEUED;
1934 queue_work(asd->delayed_init_workq, &asd->delayed_init_work);
1935 atomisp_css_set_cont_prev_start_time(isp,
1936 ATOMISP_CALC_CSS_PREV_OVERLAP(sink->height));
1937 } else {
1938 asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
1939 }
1940out:
1941 rt_mutex_unlock(&isp->mutex);
1942 return ret;
1943}
1944
1945int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1946{
1947 struct video_device *vdev = video_devdata(file);
1948 struct atomisp_device *isp = video_get_drvdata(vdev);
1949 struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1950 struct atomisp_sub_device *asd = pipe->asd;
1951 struct atomisp_video_pipe *capture_pipe = NULL;
1952 struct atomisp_video_pipe *vf_pipe = NULL;
1953 struct atomisp_video_pipe *preview_pipe = NULL;
1954 struct atomisp_video_pipe *video_pipe = NULL;
1955 struct videobuf_buffer *vb, *_vb;
1956 enum atomisp_css_pipe_id css_pipe_id;
1957 int ret;
1958 unsigned long flags;
1959 bool first_streamoff = false;
1960
1961 dev_dbg(isp->dev, "Stop stream on pad %d for asd%d\n",
1962 atomisp_subdev_source_pad(vdev), asd->index);
1963
1964 BUG_ON(!rt_mutex_is_locked(&isp->mutex));
1965 BUG_ON(!mutex_is_locked(&isp->streamoff_mutex));
1966
1967 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1968 dev_dbg(isp->dev, "unsupported v4l2 buf type\n");
1969 return -EINVAL;
1970 }
1971
1972
1973
1974
1975
1976 if ((asd->continuous_mode->val ||
1977 isp->inputs[asd->input_curr].camera_caps->multi_stream_ctrl) &&
1978 atomisp_subdev_source_pad(vdev) !=
1979 ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
1980 atomisp_subdev_source_pad(vdev) !=
1981 ATOMISP_SUBDEV_PAD_SOURCE_VIDEO) {
1982
1983 if (isp->inputs[asd->input_curr].camera_caps->multi_stream_ctrl) {
1984 v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
1985 video, s_stream, 0);
1986 } else if (atomisp_subdev_source_pad(vdev)
1987 == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE) {
1988
1989 if (asd->params.offline_parm.num_captures == -1)
1990 atomisp_css_offline_capture_configure(asd,
1991 0, 0, 0);
1992 atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_AUTO, false);
1993 }
1994
1995
1996
1997
1998
1999
2000
2001
2002 if (pipe->buffers_in_css != 0) {
2003 WARN(1, "%s: buffers of vdev %s still in CSS!\n",
2004 __func__, pipe->vdev.name);
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014 dev_warn(isp->dev, "Reset CSS to clean up css buffers.\n");
2015 atomisp_css_flush(isp);
2016 }
2017
2018 return videobuf_streamoff(&pipe->capq);
2019 }
2020
2021 if (!pipe->capq.streaming)
2022 return 0;
2023
2024 spin_lock_irqsave(&isp->lock, flags);
2025 if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) {
2026 asd->streaming = ATOMISP_DEVICE_STREAMING_STOPPING;
2027 first_streamoff = true;
2028 }
2029 spin_unlock_irqrestore(&isp->lock, flags);
2030
2031 if (first_streamoff) {
2032
2033 rt_mutex_unlock(&isp->mutex);
2034 atomisp_wdt_stop(asd, true);
2035
2036
2037
2038
2039
2040 if (isp->sw_contex.file_input)
2041 v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2042 video, s_stream, 0);
2043
2044 rt_mutex_lock(&isp->mutex);
2045 atomisp_acc_unload_extensions(asd);
2046 }
2047
2048 spin_lock_irqsave(&isp->lock, flags);
2049 if (atomisp_subdev_streaming_count(asd) == 1)
2050 asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
2051 spin_unlock_irqrestore(&isp->lock, flags);
2052
2053 if (!first_streamoff) {
2054 ret = videobuf_streamoff(&pipe->capq);
2055 if (ret)
2056 return ret;
2057 goto stopsensor;
2058 }
2059
2060 atomisp_clear_css_buffer_counters(asd);
2061
2062 if (!isp->sw_contex.file_input)
2063 atomisp_css_irq_enable(isp, CSS_IRQ_INFO_CSS_RECEIVER_SOF,
2064 false);
2065
2066 if (asd->delayed_init == ATOMISP_DELAYED_INIT_QUEUED) {
2067 cancel_work_sync(&asd->delayed_init_work);
2068 asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
2069 }
2070 if (first_streamoff) {
2071 css_pipe_id = atomisp_get_css_pipe_id(asd);
2072 ret = atomisp_css_stop(asd, css_pipe_id, false);
2073 }
2074
2075 if (asd->video_out_capture.users) {
2076 capture_pipe = &asd->video_out_capture;
2077 wake_up_interruptible(&capture_pipe->capq.wait);
2078 }
2079 if (asd->video_out_vf.users) {
2080 vf_pipe = &asd->video_out_vf;
2081 wake_up_interruptible(&vf_pipe->capq.wait);
2082 }
2083 if (asd->video_out_preview.users) {
2084 preview_pipe = &asd->video_out_preview;
2085 wake_up_interruptible(&preview_pipe->capq.wait);
2086 }
2087 if (asd->video_out_video_capture.users) {
2088 video_pipe = &asd->video_out_video_capture;
2089 wake_up_interruptible(&video_pipe->capq.wait);
2090 }
2091 ret = videobuf_streamoff(&pipe->capq);
2092 if (ret)
2093 return ret;
2094
2095
2096
2097
2098
2099 spin_lock_irqsave(&pipe->irq_lock, flags);
2100 list_for_each_entry_safe(vb, _vb, &pipe->activeq, queue) {
2101 vb->state = VIDEOBUF_PREPARED;
2102 list_del(&vb->queue);
2103 }
2104 list_for_each_entry_safe(vb, _vb, &pipe->buffers_waiting_for_param, queue) {
2105 vb->state = VIDEOBUF_PREPARED;
2106 list_del(&vb->queue);
2107 pipe->frame_request_config_id[vb->i] = 0;
2108 }
2109 spin_unlock_irqrestore(&pipe->irq_lock, flags);
2110
2111 atomisp_subdev_cleanup_pending_events(asd);
2112stopsensor:
2113 if (atomisp_subdev_streaming_count(asd) + 1
2114 != atomisp_sensor_start_stream(asd))
2115 return 0;
2116
2117 if (!isp->sw_contex.file_input)
2118 ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2119 video, s_stream, 0);
2120
2121 if (isp->flash) {
2122 asd->params.num_flash_frames = 0;
2123 asd->params.flash_state = ATOMISP_FLASH_IDLE;
2124 }
2125
2126
2127 if (atomisp_streaming_count(isp)) {
2128 atomisp_css_flush(isp);
2129 return 0;
2130 }
2131
2132
2133 if (isp->media_dev.hw_revision >= ((ATOMISP_HW_REVISION_ISP2401 <<
2134 ATOMISP_HW_REVISION_SHIFT) | ATOMISP_HW_STEPPING_B0)) {
2135 pci_write_config_word(isp->pdev, MRFLD_PCI_CSI_CONTROL,
2136 isp->saved_regs.csi_control &
2137 ~MRFLD_PCI_CSI_CONTROL_CSI_READY);
2138 }
2139
2140 if (atomisp_freq_scaling(isp, ATOMISP_DFS_MODE_LOW, false))
2141 dev_warn(isp->dev, "DFS failed.\n");
2142
2143
2144
2145
2146 if (isp->sw_contex.power_state == ATOM_ISP_POWER_UP) {
2147 unsigned int i;
2148 bool recreate_streams[MAX_STREAM_NUM] = {0};
2149 if (isp->isp_timeout)
2150 dev_err(isp->dev, "%s: Resetting with WA activated",
2151 __func__);
2152
2153
2154
2155
2156
2157
2158
2159
2160 for (i = 0; i < isp->num_of_streams; i++) {
2161 if (isp->asd[i].stream_prepared) {
2162 atomisp_destroy_pipes_stream_force(&isp->
2163 asd[i]);
2164 recreate_streams[i] = true;
2165 }
2166 }
2167
2168
2169 pci_write_config_dword(isp->pdev, PCI_I_CONTROL, isp->saved_regs.i_control |
2170 MRFLD_PCI_I_CONTROL_SRSE_RESET_MASK);
2171 dev_err(isp->dev, "atomisp_reset");
2172 atomisp_reset(isp);
2173 for (i = 0; i < isp->num_of_streams; i++) {
2174 if (recreate_streams[i])
2175 atomisp_create_pipes_stream(&isp->asd[i]);
2176 }
2177 isp->isp_timeout = false;
2178 }
2179 return ret;
2180}
2181
2182static int atomisp_streamoff(struct file *file, void *fh,
2183 enum v4l2_buf_type type)
2184{
2185 struct video_device *vdev = video_devdata(file);
2186 struct atomisp_device *isp = video_get_drvdata(vdev);
2187 int rval;
2188
2189 mutex_lock(&isp->streamoff_mutex);
2190 rt_mutex_lock(&isp->mutex);
2191 rval = __atomisp_streamoff(file, fh, type);
2192 rt_mutex_unlock(&isp->mutex);
2193 mutex_unlock(&isp->streamoff_mutex);
2194
2195 return rval;
2196}
2197
2198
2199
2200
2201
2202
2203static int atomisp_g_ctrl(struct file *file, void *fh,
2204 struct v4l2_control *control)
2205{
2206 struct video_device *vdev = video_devdata(file);
2207 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2208 struct atomisp_device *isp = video_get_drvdata(vdev);
2209 int i, ret = -EINVAL;
2210
2211 for (i = 0; i < ctrls_num; i++) {
2212 if (ci_v4l2_controls[i].id == control->id) {
2213 ret = 0;
2214 break;
2215 }
2216 }
2217
2218 if (ret)
2219 return ret;
2220
2221 rt_mutex_lock(&isp->mutex);
2222
2223 switch (control->id) {
2224 case V4L2_CID_IRIS_ABSOLUTE:
2225 case V4L2_CID_EXPOSURE_ABSOLUTE:
2226 case V4L2_CID_FNUMBER_ABSOLUTE:
2227 case V4L2_CID_2A_STATUS:
2228 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
2229 case V4L2_CID_EXPOSURE:
2230 case V4L2_CID_EXPOSURE_AUTO:
2231 case V4L2_CID_SCENE_MODE:
2232 case V4L2_CID_ISO_SENSITIVITY:
2233 case V4L2_CID_ISO_SENSITIVITY_AUTO:
2234 case V4L2_CID_CONTRAST:
2235 case V4L2_CID_SATURATION:
2236 case V4L2_CID_SHARPNESS:
2237 case V4L2_CID_3A_LOCK:
2238 case V4L2_CID_EXPOSURE_ZONE_NUM:
2239 case V4L2_CID_TEST_PATTERN:
2240 case V4L2_CID_TEST_PATTERN_COLOR_R:
2241 case V4L2_CID_TEST_PATTERN_COLOR_GR:
2242 case V4L2_CID_TEST_PATTERN_COLOR_GB:
2243 case V4L2_CID_TEST_PATTERN_COLOR_B:
2244 rt_mutex_unlock(&isp->mutex);
2245 return v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->
2246 ctrl_handler, control);
2247 case V4L2_CID_COLORFX:
2248 ret = atomisp_color_effect(asd, 0, &control->value);
2249 break;
2250 case V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION:
2251 ret = atomisp_bad_pixel(asd, 0, &control->value);
2252 break;
2253 case V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC:
2254 ret = atomisp_gdc_cac(asd, 0, &control->value);
2255 break;
2256 case V4L2_CID_ATOMISP_VIDEO_STABLIZATION:
2257 ret = atomisp_video_stable(asd, 0, &control->value);
2258 break;
2259 case V4L2_CID_ATOMISP_FIXED_PATTERN_NR:
2260 ret = atomisp_fixed_pattern(asd, 0, &control->value);
2261 break;
2262 case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION:
2263 ret = atomisp_false_color(asd, 0, &control->value);
2264 break;
2265 case V4L2_CID_ATOMISP_LOW_LIGHT:
2266 ret = atomisp_low_light(asd, 0, &control->value);
2267 break;
2268 default:
2269 ret = -EINVAL;
2270 break;
2271 }
2272
2273 rt_mutex_unlock(&isp->mutex);
2274 return ret;
2275}
2276
2277
2278
2279
2280
2281
2282static int atomisp_s_ctrl(struct file *file, void *fh,
2283 struct v4l2_control *control)
2284{
2285 struct video_device *vdev = video_devdata(file);
2286 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2287 struct atomisp_device *isp = video_get_drvdata(vdev);
2288 int i, ret = -EINVAL;
2289
2290 for (i = 0; i < ctrls_num; i++) {
2291 if (ci_v4l2_controls[i].id == control->id) {
2292 ret = 0;
2293 break;
2294 }
2295 }
2296
2297 if (ret)
2298 return ret;
2299
2300 rt_mutex_lock(&isp->mutex);
2301 switch (control->id) {
2302 case V4L2_CID_AUTO_N_PRESET_WHITE_BALANCE:
2303 case V4L2_CID_EXPOSURE:
2304 case V4L2_CID_EXPOSURE_AUTO:
2305 case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
2306 case V4L2_CID_SCENE_MODE:
2307 case V4L2_CID_ISO_SENSITIVITY:
2308 case V4L2_CID_ISO_SENSITIVITY_AUTO:
2309 case V4L2_CID_POWER_LINE_FREQUENCY:
2310 case V4L2_CID_EXPOSURE_METERING:
2311 case V4L2_CID_CONTRAST:
2312 case V4L2_CID_SATURATION:
2313 case V4L2_CID_SHARPNESS:
2314 case V4L2_CID_3A_LOCK:
2315 case V4L2_CID_COLORFX_CBCR:
2316 case V4L2_CID_TEST_PATTERN:
2317 case V4L2_CID_TEST_PATTERN_COLOR_R:
2318 case V4L2_CID_TEST_PATTERN_COLOR_GR:
2319 case V4L2_CID_TEST_PATTERN_COLOR_GB:
2320 case V4L2_CID_TEST_PATTERN_COLOR_B:
2321 rt_mutex_unlock(&isp->mutex);
2322 return v4l2_s_ctrl(NULL,
2323 isp->inputs[asd->input_curr].camera->
2324 ctrl_handler, control);
2325 case V4L2_CID_COLORFX:
2326 ret = atomisp_color_effect(asd, 1, &control->value);
2327 break;
2328 case V4L2_CID_ATOMISP_BAD_PIXEL_DETECTION:
2329 ret = atomisp_bad_pixel(asd, 1, &control->value);
2330 break;
2331 case V4L2_CID_ATOMISP_POSTPROCESS_GDC_CAC:
2332 ret = atomisp_gdc_cac(asd, 1, &control->value);
2333 break;
2334 case V4L2_CID_ATOMISP_VIDEO_STABLIZATION:
2335 ret = atomisp_video_stable(asd, 1, &control->value);
2336 break;
2337 case V4L2_CID_ATOMISP_FIXED_PATTERN_NR:
2338 ret = atomisp_fixed_pattern(asd, 1, &control->value);
2339 break;
2340 case V4L2_CID_ATOMISP_FALSE_COLOR_CORRECTION:
2341 ret = atomisp_false_color(asd, 1, &control->value);
2342 break;
2343 case V4L2_CID_REQUEST_FLASH:
2344 ret = atomisp_flash_enable(asd, control->value);
2345 break;
2346 case V4L2_CID_ATOMISP_LOW_LIGHT:
2347 ret = atomisp_low_light(asd, 1, &control->value);
2348 break;
2349 default:
2350 ret = -EINVAL;
2351 break;
2352 }
2353 rt_mutex_unlock(&isp->mutex);
2354 return ret;
2355}
2356
2357
2358
2359
2360
2361
2362static int atomisp_queryctl(struct file *file, void *fh,
2363 struct v4l2_queryctrl *qc)
2364{
2365 int i, ret = -EINVAL;
2366 struct video_device *vdev = video_devdata(file);
2367 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2368 struct atomisp_device *isp = video_get_drvdata(vdev);
2369
2370 switch (qc->id) {
2371 case V4L2_CID_FOCUS_ABSOLUTE:
2372 case V4L2_CID_FOCUS_RELATIVE:
2373 case V4L2_CID_FOCUS_STATUS:
2374#ifndef ISP2401
2375 return v4l2_queryctrl(isp->inputs[asd->input_curr].camera->
2376 ctrl_handler, qc);
2377#else
2378 if (isp->motor)
2379 return v4l2_queryctrl(isp->motor->ctrl_handler, qc);
2380 else
2381 return v4l2_queryctrl(isp->inputs[asd->input_curr].
2382 camera->ctrl_handler, qc);
2383#endif
2384 }
2385
2386 if (qc->id & V4L2_CTRL_FLAG_NEXT_CTRL)
2387 return ret;
2388
2389 for (i = 0; i < ctrls_num; i++) {
2390 if (ci_v4l2_controls[i].id == qc->id) {
2391 memcpy(qc, &ci_v4l2_controls[i],
2392 sizeof(struct v4l2_queryctrl));
2393 qc->reserved[0] = 0;
2394 ret = 0;
2395 break;
2396 }
2397 }
2398 if (ret != 0)
2399 qc->flags = V4L2_CTRL_FLAG_DISABLED;
2400
2401 return ret;
2402}
2403
2404static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh,
2405 struct v4l2_ext_controls *c)
2406{
2407 struct video_device *vdev = video_devdata(file);
2408 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2409 struct atomisp_device *isp = video_get_drvdata(vdev);
2410 struct v4l2_control ctrl;
2411 int i;
2412 int ret = 0;
2413
2414 for (i = 0; i < c->count; i++) {
2415 ctrl.id = c->controls[i].id;
2416 ctrl.value = c->controls[i].value;
2417 switch (ctrl.id) {
2418 case V4L2_CID_EXPOSURE_ABSOLUTE:
2419 case V4L2_CID_EXPOSURE_AUTO:
2420 case V4L2_CID_IRIS_ABSOLUTE:
2421 case V4L2_CID_FNUMBER_ABSOLUTE:
2422 case V4L2_CID_BIN_FACTOR_HORZ:
2423 case V4L2_CID_BIN_FACTOR_VERT:
2424 case V4L2_CID_3A_LOCK:
2425 case V4L2_CID_TEST_PATTERN:
2426 case V4L2_CID_TEST_PATTERN_COLOR_R:
2427 case V4L2_CID_TEST_PATTERN_COLOR_GR:
2428 case V4L2_CID_TEST_PATTERN_COLOR_GB:
2429 case V4L2_CID_TEST_PATTERN_COLOR_B:
2430
2431
2432
2433
2434 ret =
2435 v4l2_g_ctrl(isp->inputs[asd->input_curr].camera->
2436 ctrl_handler, &ctrl);
2437 break;
2438 case V4L2_CID_FOCUS_ABSOLUTE:
2439 case V4L2_CID_FOCUS_RELATIVE:
2440 case V4L2_CID_FOCUS_STATUS:
2441 case V4L2_CID_FOCUS_AUTO:
2442#ifndef ISP2401
2443 if (isp->inputs[asd->input_curr].motor)
2444#else
2445 if (isp->motor)
2446#endif
2447 ret =
2448#ifndef ISP2401
2449 v4l2_g_ctrl(isp->inputs[asd->input_curr].
2450 motor->ctrl_handler, &ctrl);
2451#else
2452 v4l2_g_ctrl(isp->motor->ctrl_handler,
2453 &ctrl);
2454#endif
2455 else
2456 ret =
2457 v4l2_g_ctrl(isp->inputs[asd->input_curr].
2458 camera->ctrl_handler, &ctrl);
2459 break;
2460 case V4L2_CID_FLASH_STATUS:
2461 case V4L2_CID_FLASH_INTENSITY:
2462 case V4L2_CID_FLASH_TORCH_INTENSITY:
2463 case V4L2_CID_FLASH_INDICATOR_INTENSITY:
2464 case V4L2_CID_FLASH_TIMEOUT:
2465 case V4L2_CID_FLASH_STROBE:
2466 case V4L2_CID_FLASH_MODE:
2467 case V4L2_CID_FLASH_STATUS_REGISTER:
2468 if (isp->flash)
2469 ret =
2470 v4l2_g_ctrl(isp->flash->ctrl_handler,
2471 &ctrl);
2472 break;
2473 case V4L2_CID_ZOOM_ABSOLUTE:
2474 rt_mutex_lock(&isp->mutex);
2475 ret = atomisp_digital_zoom(asd, 0, &ctrl.value);
2476 rt_mutex_unlock(&isp->mutex);
2477 break;
2478 case V4L2_CID_G_SKIP_FRAMES:
2479 ret = v4l2_subdev_call(
2480 isp->inputs[asd->input_curr].camera,
2481 sensor, g_skip_frames, (u32 *)&ctrl.value);
2482 break;
2483 default:
2484 ret = -EINVAL;
2485 }
2486
2487 if (ret) {
2488 c->error_idx = i;
2489 break;
2490 }
2491 c->controls[i].value = ctrl.value;
2492 }
2493 return ret;
2494}
2495
2496
2497static int atomisp_g_ext_ctrls(struct file *file, void *fh,
2498 struct v4l2_ext_controls *c)
2499{
2500 struct v4l2_control ctrl;
2501 int i, ret = 0;
2502
2503
2504
2505 ret = atomisp_camera_g_ext_ctrls(file, fh, c);
2506 if (ret != -EINVAL)
2507 return ret;
2508
2509 for (i = 0; i < c->count; i++) {
2510 ctrl.id = c->controls[i].id;
2511 ctrl.value = c->controls[i].value;
2512 ret = atomisp_g_ctrl(file, fh, &ctrl);
2513 c->controls[i].value = ctrl.value;
2514 if (ret) {
2515 c->error_idx = i;
2516 break;
2517 }
2518 }
2519 return ret;
2520}
2521
2522static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh,
2523 struct v4l2_ext_controls *c)
2524{
2525 struct video_device *vdev = video_devdata(file);
2526 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2527 struct atomisp_device *isp = video_get_drvdata(vdev);
2528 struct v4l2_control ctrl;
2529 int i;
2530 int ret = 0;
2531
2532 for (i = 0; i < c->count; i++) {
2533 struct v4l2_ctrl *ctr;
2534
2535 ctrl.id = c->controls[i].id;
2536 ctrl.value = c->controls[i].value;
2537 switch (ctrl.id) {
2538 case V4L2_CID_EXPOSURE_ABSOLUTE:
2539 case V4L2_CID_EXPOSURE_AUTO:
2540 case V4L2_CID_EXPOSURE_METERING:
2541 case V4L2_CID_IRIS_ABSOLUTE:
2542 case V4L2_CID_FNUMBER_ABSOLUTE:
2543 case V4L2_CID_VCM_TIMEING:
2544 case V4L2_CID_VCM_SLEW:
2545 case V4L2_CID_3A_LOCK:
2546 case V4L2_CID_TEST_PATTERN:
2547 case V4L2_CID_TEST_PATTERN_COLOR_R:
2548 case V4L2_CID_TEST_PATTERN_COLOR_GR:
2549 case V4L2_CID_TEST_PATTERN_COLOR_GB:
2550 case V4L2_CID_TEST_PATTERN_COLOR_B:
2551 ret = v4l2_s_ctrl(NULL,
2552 isp->inputs[asd->input_curr].camera->
2553 ctrl_handler, &ctrl);
2554 break;
2555 case V4L2_CID_FOCUS_ABSOLUTE:
2556 case V4L2_CID_FOCUS_RELATIVE:
2557 case V4L2_CID_FOCUS_STATUS:
2558 case V4L2_CID_FOCUS_AUTO:
2559#ifndef ISP2401
2560 if (isp->inputs[asd->input_curr].motor)
2561#else
2562 if (isp->motor)
2563#endif
2564 ret = v4l2_s_ctrl(NULL,
2565#ifndef ISP2401
2566 isp->inputs[asd->input_curr].
2567 motor->ctrl_handler, &ctrl);
2568#else
2569 isp->motor->ctrl_handler,
2570 &ctrl);
2571#endif
2572 else
2573 ret = v4l2_s_ctrl(NULL,
2574 isp->inputs[asd->input_curr].
2575 camera->ctrl_handler, &ctrl);
2576 break;
2577 case V4L2_CID_FLASH_STATUS:
2578 case V4L2_CID_FLASH_INTENSITY:
2579 case V4L2_CID_FLASH_TORCH_INTENSITY:
2580 case V4L2_CID_FLASH_INDICATOR_INTENSITY:
2581 case V4L2_CID_FLASH_TIMEOUT:
2582 case V4L2_CID_FLASH_STROBE:
2583 case V4L2_CID_FLASH_MODE:
2584 case V4L2_CID_FLASH_STATUS_REGISTER:
2585 rt_mutex_lock(&isp->mutex);
2586 if (isp->flash) {
2587 ret =
2588 v4l2_s_ctrl(NULL, isp->flash->ctrl_handler,
2589 &ctrl);
2590
2591
2592 if (ctrl.id == V4L2_CID_FLASH_MODE) {
2593 asd->params.flash_state =
2594 ATOMISP_FLASH_IDLE;
2595 asd->params.num_flash_frames = 0;
2596 }
2597 }
2598 rt_mutex_unlock(&isp->mutex);
2599 break;
2600 case V4L2_CID_ZOOM_ABSOLUTE:
2601 rt_mutex_lock(&isp->mutex);
2602 ret = atomisp_digital_zoom(asd, 1, &ctrl.value);
2603 rt_mutex_unlock(&isp->mutex);
2604 break;
2605 default:
2606 ctr = v4l2_ctrl_find(&asd->ctrl_handler, ctrl.id);
2607 if (ctr)
2608 ret = v4l2_ctrl_s_ctrl(ctr, ctrl.value);
2609 else
2610 ret = -EINVAL;
2611 }
2612
2613 if (ret) {
2614 c->error_idx = i;
2615 break;
2616 }
2617 c->controls[i].value = ctrl.value;
2618 }
2619 return ret;
2620}
2621
2622
2623static int atomisp_s_ext_ctrls(struct file *file, void *fh,
2624 struct v4l2_ext_controls *c)
2625{
2626 struct v4l2_control ctrl;
2627 int i, ret = 0;
2628
2629
2630
2631 ret = atomisp_camera_s_ext_ctrls(file, fh, c);
2632 if (ret != -EINVAL)
2633 return ret;
2634
2635 for (i = 0; i < c->count; i++) {
2636 ctrl.id = c->controls[i].id;
2637 ctrl.value = c->controls[i].value;
2638 ret = atomisp_s_ctrl(file, fh, &ctrl);
2639 c->controls[i].value = ctrl.value;
2640 if (ret) {
2641 c->error_idx = i;
2642 break;
2643 }
2644 }
2645 return ret;
2646}
2647
2648
2649
2650
2651static int atomisp_g_parm(struct file *file, void *fh,
2652 struct v4l2_streamparm *parm)
2653{
2654 struct video_device *vdev = video_devdata(file);
2655 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2656 struct atomisp_device *isp = video_get_drvdata(vdev);
2657
2658 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2659 dev_err(isp->dev, "unsupport v4l2 buf type\n");
2660 return -EINVAL;
2661 }
2662
2663 rt_mutex_lock(&isp->mutex);
2664 parm->parm.capture.capturemode = asd->run_mode->val;
2665 rt_mutex_unlock(&isp->mutex);
2666
2667 return 0;
2668}
2669
2670static int atomisp_s_parm(struct file *file, void *fh,
2671 struct v4l2_streamparm *parm)
2672{
2673 struct video_device *vdev = video_devdata(file);
2674 struct atomisp_device *isp = video_get_drvdata(vdev);
2675 struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd;
2676 int mode;
2677 int rval;
2678 int fps;
2679
2680 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2681 dev_err(isp->dev, "unsupport v4l2 buf type\n");
2682 return -EINVAL;
2683 }
2684
2685 rt_mutex_lock(&isp->mutex);
2686
2687 asd->high_speed_mode = false;
2688 switch (parm->parm.capture.capturemode) {
2689 case CI_MODE_NONE: {
2690 struct v4l2_subdev_frame_interval fi = {0};
2691
2692 fi.interval = parm->parm.capture.timeperframe;
2693
2694 rval = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2695 video, s_frame_interval, &fi);
2696 if (!rval)
2697 parm->parm.capture.timeperframe = fi.interval;
2698
2699 if (fi.interval.numerator != 0) {
2700 fps = fi.interval.denominator / fi.interval.numerator;
2701 if (fps > 30)
2702 asd->high_speed_mode = true;
2703 }
2704
2705 goto out;
2706 }
2707 case CI_MODE_VIDEO:
2708 mode = ATOMISP_RUN_MODE_VIDEO;
2709 break;
2710 case CI_MODE_STILL_CAPTURE:
2711 mode = ATOMISP_RUN_MODE_STILL_CAPTURE;
2712 break;
2713 case CI_MODE_CONTINUOUS:
2714 mode = ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE;
2715 break;
2716 case CI_MODE_PREVIEW:
2717 mode = ATOMISP_RUN_MODE_PREVIEW;
2718 break;
2719 default:
2720 rval = -EINVAL;
2721 goto out;
2722 }
2723
2724 rval = v4l2_ctrl_s_ctrl(asd->run_mode, mode);
2725
2726out:
2727 rt_mutex_unlock(&isp->mutex);
2728
2729 return rval == -ENOIOCTLCMD ? 0 : rval;
2730}
2731
2732static int atomisp_s_parm_file(struct file *file, void *fh,
2733 struct v4l2_streamparm *parm)
2734{
2735 struct video_device *vdev = video_devdata(file);
2736 struct atomisp_device *isp = video_get_drvdata(vdev);
2737
2738 if (parm->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
2739 dev_err(isp->dev, "unsupport v4l2 buf type for output\n");
2740 return -EINVAL;
2741 }
2742
2743 rt_mutex_lock(&isp->mutex);
2744 isp->sw_contex.file_input = 1;
2745 rt_mutex_unlock(&isp->mutex);
2746
2747 return 0;
2748}
2749
2750static long atomisp_vidioc_default(struct file *file, void *fh,
2751 bool valid_prio, unsigned int cmd, void *arg)
2752{
2753 struct video_device *vdev = video_devdata(file);
2754 struct atomisp_device *isp = video_get_drvdata(vdev);
2755 struct atomisp_sub_device *asd;
2756 bool acc_node;
2757 int err;
2758
2759 acc_node = !strncmp(vdev->name, "ATOMISP ISP ACC",
2760 sizeof(vdev->name));
2761 if (acc_node)
2762 asd = atomisp_to_acc_pipe(vdev)->asd;
2763 else
2764 asd = atomisp_to_video_pipe(vdev)->asd;
2765
2766 switch (cmd) {
2767 case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
2768 case ATOMISP_IOC_S_EXPOSURE:
2769 case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
2770 case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
2771 case ATOMISP_IOC_EXT_ISP_CTRL:
2772 case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO:
2773 case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE:
2774 case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE:
2775 case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT:
2776 case ATOMISP_IOC_S_SENSOR_EE_CONFIG:
2777#ifdef ISP2401
2778 case ATOMISP_IOC_G_UPDATE_EXPOSURE:
2779#endif
2780
2781 break;
2782 default:
2783 rt_mutex_lock(&isp->mutex);
2784 break;
2785 }
2786 switch (cmd) {
2787#ifdef ISP2401
2788 case ATOMISP_IOC_S_SENSOR_RUNMODE:
2789 err = atomisp_set_sensor_runmode(asd, arg);
2790 break;
2791
2792#endif
2793 case ATOMISP_IOC_G_XNR:
2794 err = atomisp_xnr(asd, 0, arg);
2795 break;
2796
2797 case ATOMISP_IOC_S_XNR:
2798 err = atomisp_xnr(asd, 1, arg);
2799 break;
2800
2801 case ATOMISP_IOC_G_NR:
2802 err = atomisp_nr(asd, 0, arg);
2803 break;
2804
2805 case ATOMISP_IOC_S_NR:
2806 err = atomisp_nr(asd, 1, arg);
2807 break;
2808
2809 case ATOMISP_IOC_G_TNR:
2810 err = atomisp_tnr(asd, 0, arg);
2811 break;
2812
2813 case ATOMISP_IOC_S_TNR:
2814 err = atomisp_tnr(asd, 1, arg);
2815 break;
2816
2817 case ATOMISP_IOC_G_BLACK_LEVEL_COMP:
2818 err = atomisp_black_level(asd, 0, arg);
2819 break;
2820
2821 case ATOMISP_IOC_S_BLACK_LEVEL_COMP:
2822 err = atomisp_black_level(asd, 1, arg);
2823 break;
2824
2825 case ATOMISP_IOC_G_EE:
2826 err = atomisp_ee(asd, 0, arg);
2827 break;
2828
2829 case ATOMISP_IOC_S_EE:
2830 err = atomisp_ee(asd, 1, arg);
2831 break;
2832
2833 case ATOMISP_IOC_G_DIS_STAT:
2834 err = atomisp_get_dis_stat(asd, arg);
2835 break;
2836
2837 case ATOMISP_IOC_G_DVS2_BQ_RESOLUTIONS:
2838 err = atomisp_get_dvs2_bq_resolutions(asd, arg);
2839 break;
2840
2841 case ATOMISP_IOC_S_DIS_COEFS:
2842 err = atomisp_css_cp_dvs2_coefs(asd, arg,
2843 &asd->params.css_param, true);
2844 if (!err && arg)
2845 asd->params.css_update_params_needed = true;
2846 break;
2847
2848 case ATOMISP_IOC_S_DIS_VECTOR:
2849 err = atomisp_cp_dvs_6axis_config(asd, arg,
2850 &asd->params.css_param, true);
2851 if (!err && arg)
2852 asd->params.css_update_params_needed = true;
2853 break;
2854
2855 case ATOMISP_IOC_G_ISP_PARM:
2856 err = atomisp_param(asd, 0, arg);
2857 break;
2858
2859 case ATOMISP_IOC_S_ISP_PARM:
2860 err = atomisp_param(asd, 1, arg);
2861 break;
2862
2863 case ATOMISP_IOC_G_3A_STAT:
2864 err = atomisp_3a_stat(asd, 0, arg);
2865 break;
2866
2867 case ATOMISP_IOC_G_ISP_GAMMA:
2868 err = atomisp_gamma(asd, 0, arg);
2869 break;
2870
2871 case ATOMISP_IOC_S_ISP_GAMMA:
2872 err = atomisp_gamma(asd, 1, arg);
2873 break;
2874
2875 case ATOMISP_IOC_G_ISP_GDC_TAB:
2876 err = atomisp_gdc_cac_table(asd, 0, arg);
2877 break;
2878
2879 case ATOMISP_IOC_S_ISP_GDC_TAB:
2880 err = atomisp_gdc_cac_table(asd, 1, arg);
2881 break;
2882
2883 case ATOMISP_IOC_G_ISP_MACC:
2884 err = atomisp_macc_table(asd, 0, arg);
2885 break;
2886
2887 case ATOMISP_IOC_S_ISP_MACC:
2888 err = atomisp_macc_table(asd, 1, arg);
2889 break;
2890
2891 case ATOMISP_IOC_G_ISP_BAD_PIXEL_DETECTION:
2892 err = atomisp_bad_pixel_param(asd, 0, arg);
2893 break;
2894
2895 case ATOMISP_IOC_S_ISP_BAD_PIXEL_DETECTION:
2896 err = atomisp_bad_pixel_param(asd, 1, arg);
2897 break;
2898
2899 case ATOMISP_IOC_G_ISP_FALSE_COLOR_CORRECTION:
2900 err = atomisp_false_color_param(asd, 0, arg);
2901 break;
2902
2903 case ATOMISP_IOC_S_ISP_FALSE_COLOR_CORRECTION:
2904 err = atomisp_false_color_param(asd, 1, arg);
2905 break;
2906
2907 case ATOMISP_IOC_G_ISP_CTC:
2908 err = atomisp_ctc(asd, 0, arg);
2909 break;
2910
2911 case ATOMISP_IOC_S_ISP_CTC:
2912 err = atomisp_ctc(asd, 1, arg);
2913 break;
2914
2915 case ATOMISP_IOC_G_ISP_WHITE_BALANCE:
2916 err = atomisp_white_balance_param(asd, 0, arg);
2917 break;
2918
2919 case ATOMISP_IOC_S_ISP_WHITE_BALANCE:
2920 err = atomisp_white_balance_param(asd, 1, arg);
2921 break;
2922
2923 case ATOMISP_IOC_G_3A_CONFIG:
2924 err = atomisp_3a_config_param(asd, 0, arg);
2925 break;
2926
2927 case ATOMISP_IOC_S_3A_CONFIG:
2928 err = atomisp_3a_config_param(asd, 1, arg);
2929 break;
2930
2931 case ATOMISP_IOC_S_ISP_FPN_TABLE:
2932 err = atomisp_fixed_pattern_table(asd, arg);
2933 break;
2934
2935 case ATOMISP_IOC_ISP_MAKERNOTE:
2936 err = atomisp_exif_makernote(asd, arg);
2937 break;
2938
2939 case ATOMISP_IOC_G_SENSOR_MODE_DATA:
2940 err = atomisp_get_sensor_mode_data(asd, arg);
2941 break;
2942
2943 case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
2944#ifndef ISP2401
2945 if (isp->inputs[asd->input_curr].motor)
2946#else
2947 if (isp->motor)
2948#endif
2949 err = v4l2_subdev_call(
2950#ifndef ISP2401
2951 isp->inputs[asd->input_curr].motor,
2952#else
2953 isp->motor,
2954#endif
2955 core, ioctl, cmd, arg);
2956 else
2957 err = v4l2_subdev_call(
2958 isp->inputs[asd->input_curr].camera,
2959 core, ioctl, cmd, arg);
2960 break;
2961
2962 case ATOMISP_IOC_S_EXPOSURE:
2963 case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
2964 case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
2965 case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO:
2966 case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE:
2967 case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE:
2968 case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT:
2969#ifdef ISP2401
2970 case ATOMISP_IOC_G_UPDATE_EXPOSURE:
2971#endif
2972 err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
2973 core, ioctl, cmd, arg);
2974 break;
2975
2976 case ATOMISP_IOC_ACC_LOAD:
2977 err = atomisp_acc_load(asd, arg);
2978 break;
2979
2980 case ATOMISP_IOC_ACC_LOAD_TO_PIPE:
2981 err = atomisp_acc_load_to_pipe(asd, arg);
2982 break;
2983
2984 case ATOMISP_IOC_ACC_UNLOAD:
2985 err = atomisp_acc_unload(asd, arg);
2986 break;
2987
2988 case ATOMISP_IOC_ACC_START:
2989 err = atomisp_acc_start(asd, arg);
2990 break;
2991
2992 case ATOMISP_IOC_ACC_WAIT:
2993 err = atomisp_acc_wait(asd, arg);
2994 break;
2995
2996 case ATOMISP_IOC_ACC_MAP:
2997 err = atomisp_acc_map(asd, arg);
2998 break;
2999
3000 case ATOMISP_IOC_ACC_UNMAP:
3001 err = atomisp_acc_unmap(asd, arg);
3002 break;
3003
3004 case ATOMISP_IOC_ACC_S_MAPPED_ARG:
3005 err = atomisp_acc_s_mapped_arg(asd, arg);
3006 break;
3007
3008 case ATOMISP_IOC_S_ISP_SHD_TAB:
3009 err = atomisp_set_shading_table(asd, arg);
3010 break;
3011
3012 case ATOMISP_IOC_G_ISP_GAMMA_CORRECTION:
3013 err = atomisp_gamma_correction(asd, 0, arg);
3014 break;
3015
3016 case ATOMISP_IOC_S_ISP_GAMMA_CORRECTION:
3017 err = atomisp_gamma_correction(asd, 1, arg);
3018 break;
3019
3020 case ATOMISP_IOC_S_PARAMETERS:
3021 err = atomisp_set_parameters(vdev, arg);
3022 break;
3023
3024 case ATOMISP_IOC_S_CONT_CAPTURE_CONFIG:
3025 err = atomisp_offline_capture_configure(asd, arg);
3026 break;
3027 case ATOMISP_IOC_G_METADATA:
3028 err = atomisp_get_metadata(asd, 0, arg);
3029 break;
3030 case ATOMISP_IOC_G_METADATA_BY_TYPE:
3031 err = atomisp_get_metadata_by_type(asd, 0, arg);
3032 break;
3033 case ATOMISP_IOC_EXT_ISP_CTRL:
3034 err = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
3035 core, ioctl, cmd, arg);
3036 break;
3037 case ATOMISP_IOC_EXP_ID_UNLOCK:
3038 err = atomisp_exp_id_unlock(asd, arg);
3039 break;
3040 case ATOMISP_IOC_EXP_ID_CAPTURE:
3041 err = atomisp_exp_id_capture(asd, arg);
3042 break;
3043 case ATOMISP_IOC_S_ENABLE_DZ_CAPT_PIPE:
3044 err = atomisp_enable_dz_capt_pipe(asd, arg);
3045 break;
3046 case ATOMISP_IOC_G_FORMATS_CONFIG:
3047 err = atomisp_formats(asd, 0, arg);
3048 break;
3049
3050 case ATOMISP_IOC_S_FORMATS_CONFIG:
3051 err = atomisp_formats(asd, 1, arg);
3052 break;
3053 case ATOMISP_IOC_S_EXPOSURE_WINDOW:
3054 err = atomisp_s_ae_window(asd, arg);
3055 break;
3056 case ATOMISP_IOC_S_ACC_STATE:
3057 err = atomisp_acc_set_state(asd, arg);
3058 break;
3059 case ATOMISP_IOC_G_ACC_STATE:
3060 err = atomisp_acc_get_state(asd, arg);
3061 break;
3062 case ATOMISP_IOC_INJECT_A_FAKE_EVENT:
3063 err = atomisp_inject_a_fake_event(asd, arg);
3064 break;
3065 case ATOMISP_IOC_G_INVALID_FRAME_NUM:
3066 err = atomisp_get_invalid_frame_num(vdev, arg);
3067 break;
3068 case ATOMISP_IOC_S_ARRAY_RESOLUTION:
3069 err = atomisp_set_array_res(asd, arg);
3070 break;
3071 default:
3072 err = -EINVAL;
3073 break;
3074 }
3075
3076 switch (cmd) {
3077 case ATOMISP_IOC_G_MOTOR_PRIV_INT_DATA:
3078 case ATOMISP_IOC_S_EXPOSURE:
3079 case ATOMISP_IOC_G_SENSOR_CALIBRATION_GROUP:
3080 case ATOMISP_IOC_G_SENSOR_PRIV_INT_DATA:
3081 case ATOMISP_IOC_EXT_ISP_CTRL:
3082 case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_INFO:
3083 case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_MODE:
3084 case ATOMISP_IOC_G_SENSOR_AE_BRACKETING_MODE:
3085 case ATOMISP_IOC_S_SENSOR_AE_BRACKETING_LUT:
3086#ifdef ISP2401
3087 case ATOMISP_IOC_G_UPDATE_EXPOSURE:
3088#endif
3089 break;
3090 default:
3091 rt_mutex_unlock(&isp->mutex);
3092 break;
3093 }
3094 return err;
3095}
3096
3097const struct v4l2_ioctl_ops atomisp_ioctl_ops = {
3098 .vidioc_querycap = atomisp_querycap,
3099 .vidioc_enum_input = atomisp_enum_input,
3100 .vidioc_g_input = atomisp_g_input,
3101 .vidioc_s_input = atomisp_s_input,
3102 .vidioc_queryctrl = atomisp_queryctl,
3103 .vidioc_s_ctrl = atomisp_s_ctrl,
3104 .vidioc_g_ctrl = atomisp_g_ctrl,
3105 .vidioc_s_ext_ctrls = atomisp_s_ext_ctrls,
3106 .vidioc_g_ext_ctrls = atomisp_g_ext_ctrls,
3107 .vidioc_enum_fmt_vid_cap = atomisp_enum_fmt_cap,
3108 .vidioc_try_fmt_vid_cap = atomisp_try_fmt_cap,
3109 .vidioc_g_fmt_vid_cap = atomisp_g_fmt_cap,
3110 .vidioc_s_fmt_vid_cap = atomisp_s_fmt_cap,
3111 .vidioc_reqbufs = atomisp_reqbufs,
3112 .vidioc_querybuf = atomisp_querybuf,
3113 .vidioc_qbuf = atomisp_qbuf,
3114 .vidioc_dqbuf = atomisp_dqbuf,
3115 .vidioc_streamon = atomisp_streamon,
3116 .vidioc_streamoff = atomisp_streamoff,
3117 .vidioc_default = atomisp_vidioc_default,
3118 .vidioc_s_parm = atomisp_s_parm,
3119 .vidioc_g_parm = atomisp_g_parm,
3120};
3121
3122const struct v4l2_ioctl_ops atomisp_file_ioctl_ops = {
3123 .vidioc_querycap = atomisp_querycap,
3124 .vidioc_g_fmt_vid_out = atomisp_g_fmt_file,
3125 .vidioc_s_fmt_vid_out = atomisp_s_fmt_file,
3126 .vidioc_s_parm = atomisp_s_parm_file,
3127 .vidioc_reqbufs = atomisp_reqbufs_file,
3128 .vidioc_querybuf = atomisp_querybuf_file,
3129 .vidioc_qbuf = atomisp_qbuf_file,
3130};
3131