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