ENGR00117261 V4L2 capture:CSI input cropping improvement
[efikamx:linux-kernel.git] / drivers / media / video / mxc / capture / mxc_v4l2_capture.c
1 /*
2  * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
3  */
4
5 /*
6  * The code contained herein is licensed under the GNU General Public
7  * License. You may obtain a copy of the GNU General Public License
8  * Version 2 or later at the following locations:
9  *
10  * http://www.opensource.org/licenses/gpl-license.html
11  * http://www.gnu.org/copyleft/gpl.html
12  */
13
14 /*!
15  * @file drivers/media/video/mxc/capture/mxc_v4l2_capture.c
16  *
17  * @brief Mxc Video For Linux 2 driver
18  *
19  * @ingroup MXC_V4L2_CAPTURE
20  */
21 #include <linux/version.h>
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/platform_device.h>
25 #include <linux/fs.h>
26 #include <linux/slab.h>
27 #include <linux/ctype.h>
28 #include <linux/io.h>
29 #include <linux/semaphore.h>
30 #include <linux/pagemap.h>
31 #include <linux/vmalloc.h>
32 #include <linux/types.h>
33 #include <linux/fb.h>
34 #include <linux/dma-mapping.h>
35 #include <linux/mxcfb.h>
36 #include <media/v4l2-ioctl.h>
37 #include <media/v4l2-int-device.h>
38 #include "mxc_v4l2_capture.h"
39 #include "ipu_prp_sw.h"
40
41 static int video_nr = -1;
42 static cam_data *g_cam;
43
44 /*! This data is used for the output to the display. */
45 #define MXC_V4L2_CAPTURE_NUM_OUTPUTS    3
46 #define MXC_V4L2_CAPTURE_NUM_INPUTS     2
47 static struct v4l2_output mxc_capture_outputs[MXC_V4L2_CAPTURE_NUM_OUTPUTS] = {
48         {
49          .index = 0,
50          .name = "DISP3 BG",
51          .type = V4L2_OUTPUT_TYPE_ANALOG,
52          .audioset = 0,
53          .modulator = 0,
54          .std = V4L2_STD_UNKNOWN,
55          },
56         {
57          .index = 1,
58          .name = "DISP0",
59          .type = V4L2_OUTPUT_TYPE_ANALOG,
60          .audioset = 0,
61          .modulator = 0,
62          .std = V4L2_STD_UNKNOWN,
63          },
64         {
65          .index = 2,
66          .name = "DISP3 FG",
67          .type = V4L2_OUTPUT_TYPE_ANALOG,
68          .audioset = 0,
69          .modulator = 0,
70          .std = V4L2_STD_UNKNOWN,
71          },
72 };
73
74 static struct v4l2_input mxc_capture_inputs[MXC_V4L2_CAPTURE_NUM_INPUTS] = {
75         {
76          .index = 0,
77          .name = "CSI IC MEM",
78          .type = V4L2_INPUT_TYPE_CAMERA,
79          .audioset = 0,
80          .tuner = 0,
81          .std = V4L2_STD_UNKNOWN,
82          .status = 0,
83          },
84         {
85          .index = 1,
86          .name = "CSI MEM",
87          .type = V4L2_INPUT_TYPE_CAMERA,
88          .audioset = 0,
89          .tuner = 0,
90          .std = V4L2_STD_UNKNOWN,
91          .status = V4L2_IN_ST_NO_POWER,
92          },
93 };
94
95 /*! List of TV input video formats supported. The video formats is corresponding
96  * to the v4l2_id in video_fmt_t.
97  * Currently, only PAL and NTSC is supported. Needs to be expanded in the
98  * future.
99  */
100 typedef enum {
101         TV_NTSC = 0,            /*!< Locked on (M) NTSC video signal. */
102         TV_PAL,                 /*!< (B, G, H, I, N)PAL video signal. */
103         TV_NOT_LOCKED,          /*!< Not locked on a signal. */
104 } video_fmt_idx;
105
106 /*! Number of video standards supported (including 'not locked' signal). */
107 #define TV_STD_MAX              (TV_NOT_LOCKED + 1)
108
109 /*! Video format structure. */
110 typedef struct {
111         int v4l2_id;            /*!< Video for linux ID. */
112         char name[16];          /*!< Name (e.g., "NTSC", "PAL", etc.) */
113         u16 raw_width;          /*!< Raw width. */
114         u16 raw_height;         /*!< Raw height. */
115         u16 active_width;       /*!< Active width. */
116         u16 active_height;      /*!< Active height. */
117         u16 active_top;         /*!< Active top. */
118         u16 active_left;        /*!< Active left. */
119 } video_fmt_t;
120
121 /*!
122  * Description of video formats supported.
123  *
124  *  PAL: raw=720x625, active=720x576.
125  *  NTSC: raw=720x525, active=720x480.
126  */
127 static video_fmt_t video_fmts[] = {
128         {                       /*! NTSC */
129          .v4l2_id = V4L2_STD_NTSC,
130          .name = "NTSC",
131          .raw_width = 720 - 1,          /* SENS_FRM_WIDTH */
132          .raw_height = 288 - 1,         /* SENS_FRM_HEIGHT */
133          .active_width = 720,           /* ACT_FRM_WIDTH plus 1 */
134          .active_height = (480 / 2),    /* ACT_FRM_HEIGHT plus 1 */
135          .active_top = 12,
136          .active_left = 0,
137          },
138         {                       /*! (B, G, H, I, N) PAL */
139          .v4l2_id = V4L2_STD_PAL,
140          .name = "PAL",
141          .raw_width = 720 - 1,
142          .raw_height = (576 / 2) + 24 * 2 - 1,
143          .active_width = 720,
144          .active_height = (576 / 2),
145          .active_top = 0,
146          .active_left = 0,
147          },
148         {                       /*! Unlocked standard */
149          .v4l2_id = V4L2_STD_ALL,
150          .name = "Autodetect",
151          .raw_width = 720 - 1,
152          .raw_height = (576 / 2) + 24 * 2 - 1,
153          .active_width = 720,
154          .active_height = (576 / 2),
155          .active_top = 0,
156          .active_left = 0,
157          },
158 };
159
160 /*!* Standard index of TV. */
161 static video_fmt_idx video_index = TV_NOT_LOCKED;
162
163 static int mxc_v4l2_master_attach(struct v4l2_int_device *slave);
164 static void mxc_v4l2_master_detach(struct v4l2_int_device *slave);
165 static u8 camera_power(cam_data *cam, bool cameraOn);
166
167 /*! Information about this driver. */
168 static struct v4l2_int_master mxc_v4l2_master = {
169         .attach = mxc_v4l2_master_attach,
170         .detach = mxc_v4l2_master_detach,
171 };
172
173 static struct v4l2_int_device mxc_v4l2_int_device = {
174         .module = THIS_MODULE,
175         .name = "mxc_v4l2_cap",
176         .type = v4l2_int_type_master,
177         .u = {
178                 .master = &mxc_v4l2_master,
179                 },
180 };
181
182 /***************************************************************************
183  * Functions for handling Frame buffers.
184  **************************************************************************/
185
186 /*!
187  * Free frame buffers
188  *
189  * @param cam      Structure cam_data *
190  *
191  * @return status  0 success.
192  */
193 static int mxc_free_frame_buf(cam_data *cam)
194 {
195         int i;
196
197         pr_debug("MVC: In mxc_free_frame_buf\n");
198
199         for (i = 0; i < FRAME_NUM; i++) {
200                 if (cam->frame[i].vaddress != 0) {
201                         dma_free_coherent(0, cam->frame[i].buffer.length,
202                                           cam->frame[i].vaddress,
203                                           cam->frame[i].paddress);
204                         cam->frame[i].vaddress = 0;
205                 }
206         }
207
208         return 0;
209 }
210
211 /*!
212  * Allocate frame buffers
213  *
214  * @param cam      Structure cam_data*
215  * @param count    int number of buffer need to allocated
216  *
217  * @return status  -0 Successfully allocated a buffer, -ENOBUFS failed.
218  */
219 static int mxc_allocate_frame_buf(cam_data *cam, int count)
220 {
221         int i;
222
223         pr_debug("In MVC:mxc_allocate_frame_buf - size=%d\n",
224                 cam->v2f.fmt.pix.sizeimage);
225
226         for (i = 0; i < count; i++) {
227                 cam->frame[i].vaddress =
228                     dma_alloc_coherent(0,
229                                        PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
230                                        &cam->frame[i].paddress,
231                                        GFP_DMA | GFP_KERNEL);
232                 if (cam->frame[i].vaddress == 0) {
233                         pr_err("ERROR: v4l2 capture: "
234                                 "mxc_allocate_frame_buf failed.\n");
235                         mxc_free_frame_buf(cam);
236                         return -ENOBUFS;
237                 }
238                 cam->frame[i].buffer.index = i;
239                 cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
240                 cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
241                 cam->frame[i].buffer.length =
242                     PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
243                 cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP;
244                 cam->frame[i].buffer.m.offset = cam->frame[i].paddress;
245                 cam->frame[i].index = i;
246         }
247
248         return 0;
249 }
250
251 /*!
252  * Free frame buffers status
253  *
254  * @param cam    Structure cam_data *
255  *
256  * @return none
257  */
258 static void mxc_free_frames(cam_data *cam)
259 {
260         int i;
261
262         pr_debug("In MVC:mxc_free_frames\n");
263
264         for (i = 0; i < FRAME_NUM; i++) {
265                 cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
266         }
267
268         cam->enc_counter = 0;
269         cam->skip_frame = 0;
270         INIT_LIST_HEAD(&cam->ready_q);
271         INIT_LIST_HEAD(&cam->working_q);
272         INIT_LIST_HEAD(&cam->done_q);
273 }
274
275 /*!
276  * Return the buffer status
277  *
278  * @param cam      Structure cam_data *
279  * @param buf      Structure v4l2_buffer *
280  *
281  * @return status  0 success, EINVAL failed.
282  */
283 static int mxc_v4l2_buffer_status(cam_data *cam, struct v4l2_buffer *buf)
284 {
285         pr_debug("In MVC:mxc_v4l2_buffer_status\n");
286
287         if (buf->index < 0 || buf->index >= FRAME_NUM) {
288                 pr_err("ERROR: v4l2 capture: mxc_v4l2_buffer_status buffers "
289                        "not allocated\n");
290                 return -EINVAL;
291         }
292
293         memcpy(buf, &(cam->frame[buf->index].buffer), sizeof(*buf));
294         return 0;
295 }
296
297 /***************************************************************************
298  * Functions for handling the video stream.
299  **************************************************************************/
300
301 /*!
302  * Indicates whether the palette is supported.
303  *
304  * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_BGR24 or V4L2_PIX_FMT_BGR32
305  *
306  * @return 0 if failed
307  */
308 static inline int valid_mode(u32 palette)
309 {
310         return ((palette == V4L2_PIX_FMT_RGB565) ||
311                 (palette == V4L2_PIX_FMT_BGR24) ||
312                 (palette == V4L2_PIX_FMT_RGB24) ||
313                 (palette == V4L2_PIX_FMT_BGR32) ||
314                 (palette == V4L2_PIX_FMT_RGB32) ||
315                 (palette == V4L2_PIX_FMT_YUV422P) ||
316                 (palette == V4L2_PIX_FMT_UYVY) ||
317                 (palette == V4L2_PIX_FMT_YUV420) ||
318                 (palette == V4L2_PIX_FMT_NV12));
319 }
320
321 /*!
322  * Start the encoder job
323  *
324  * @param cam      structure cam_data *
325  *
326  * @return status  0 Success
327  */
328 static int mxc_streamon(cam_data *cam)
329 {
330         struct mxc_v4l_frame *frame;
331         int err = 0;
332
333         pr_debug("In MVC:mxc_streamon\n");
334
335         if (NULL == cam) {
336                 pr_err("ERROR! cam parameter is NULL\n");
337                 return -1;
338         }
339
340         if (list_empty(&cam->ready_q)) {
341                 pr_err("ERROR: v4l2 capture: mxc_streamon buffer has not been "
342                         "queued yet\n");
343                 return -EINVAL;
344         }
345
346         cam->capture_pid = current->pid;
347
348         if (cam->enc_enable) {
349                 err = cam->enc_enable(cam);
350                 if (err != 0) {
351                         return err;
352                 }
353         }
354
355         cam->ping_pong_csi = 0;
356         if (cam->enc_update_eba) {
357                 frame =
358                     list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
359                 list_del(cam->ready_q.next);
360                 list_add_tail(&frame->queue, &cam->working_q);
361                 err = cam->enc_update_eba(frame->buffer.m.offset,
362                                           &cam->ping_pong_csi);
363
364                 frame =
365                     list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
366                 list_del(cam->ready_q.next);
367                 list_add_tail(&frame->queue, &cam->working_q);
368                 err |= cam->enc_update_eba(frame->buffer.m.offset,
369                                            &cam->ping_pong_csi);
370         } else {
371                 return -EINVAL;
372         }
373
374         cam->capture_on = true;
375
376         return err;
377 }
378
379 /*!
380  * Shut down the encoder job
381  *
382  * @param cam      structure cam_data *
383  *
384  * @return status  0 Success
385  */
386 static int mxc_streamoff(cam_data *cam)
387 {
388         int err = 0;
389
390         pr_debug("In MVC:mxc_streamoff\n");
391
392         if (cam->capture_on == false)
393                 return 0;
394
395         if (cam->enc_disable) {
396                 err = cam->enc_disable(cam);
397         }
398         mxc_free_frames(cam);
399         mxc_capture_inputs[cam->current_input].status |= V4L2_IN_ST_NO_POWER;
400         cam->capture_on = false;
401         return err;
402 }
403
404 /*!
405  * Valid and adjust the overlay window size, position
406  *
407  * @param cam      structure cam_data *
408  * @param win      struct v4l2_window  *
409  *
410  * @return 0
411  */
412 static int verify_preview(cam_data *cam, struct v4l2_window *win)
413 {
414         int i = 0, width_bound = 0, height_bound = 0;
415         int *width, *height;
416         struct fb_info *bg_fbi = NULL;
417         bool foregound_fb;
418
419         pr_debug("In MVC: verify_preview\n");
420
421         do {
422                 cam->overlay_fb = (struct fb_info *)registered_fb[i];
423                 if (cam->overlay_fb == NULL) {
424                         pr_err("ERROR: verify_preview frame buffer NULL.\n");
425                         return -1;
426                 }
427                 if (strcmp(cam->overlay_fb->fix.id, "DISP3 BG") == 0)
428                         bg_fbi = cam->overlay_fb;
429                 if (strcmp(cam->overlay_fb->fix.id,
430                             mxc_capture_outputs[cam->output].name) == 0) {
431                         if (strcmp(cam->overlay_fb->fix.id, "DISP3 FG") == 0)
432                                 foregound_fb = true;
433                         break;
434                 }
435         } while (++i < FB_MAX);
436
437         if (foregound_fb) {
438                 width_bound = bg_fbi->var.xres;
439                 height_bound = bg_fbi->var.yres;
440
441                 if (win->w.width + win->w.left > bg_fbi->var.xres ||
442                     win->w.height + win->w.top > bg_fbi->var.yres) {
443                         pr_err("ERROR: FG window position exceeds.\n");
444                         return -1;
445                 }
446         } else {
447                 /* 4 bytes alignment for BG */
448                 width_bound = cam->overlay_fb->var.xres;
449                 height_bound = cam->overlay_fb->var.yres;
450
451                 if (cam->overlay_fb->var.bits_per_pixel == 24) {
452                         win->w.left -= win->w.left % 4;
453                 } else if (cam->overlay_fb->var.bits_per_pixel == 16) {
454                         win->w.left -= win->w.left % 2;
455                 }
456
457                 if (win->w.width + win->w.left > cam->overlay_fb->var.xres)
458                         win->w.width = cam->overlay_fb->var.xres - win->w.left;
459                 if (win->w.height + win->w.top > cam->overlay_fb->var.yres)
460                         win->w.height = cam->overlay_fb->var.yres - win->w.top;
461         }
462
463         /* stride line limitation */
464         win->w.height -= win->w.height % 8;
465         win->w.width -= win->w.width % 8;
466
467         if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
468                 height = &win->w.width;
469                 width = &win->w.height;
470         } else {
471                 width = &win->w.width;
472                 height = &win->w.height;
473         }
474
475         if ((cam->crop_bounds.width / *width > 8) ||
476             ((cam->crop_bounds.width / *width == 8) &&
477              (cam->crop_bounds.width % *width))) {
478                 *width = cam->crop_bounds.width / 8;
479                 if (*width % 8)
480                         *width += 8 - *width % 8;
481                 if (*width + win->w.left > width_bound) {
482                         pr_err("ERROR: v4l2 capture: width exceeds "
483                                 "resize limit.\n");
484                         return -1;
485                 }
486                 pr_err("ERROR: v4l2 capture: width exceeds limit. "
487                         "Resize to %d.\n",
488                         *width);
489         }
490
491         if ((cam->crop_bounds.height / *height > 8) ||
492             ((cam->crop_bounds.height / *height == 8) &&
493              (cam->crop_bounds.height % *height))) {
494                 *height = cam->crop_bounds.height / 8;
495                 if (*height % 8)
496                         *height += 8 - *height % 8;
497                 if (*height + win->w.top > height_bound) {
498                         pr_err("ERROR: v4l2 capture: height exceeds "
499                                 "resize limit.\n");
500                         return -1;
501                 }
502                 pr_err("ERROR: v4l2 capture: height exceeds limit "
503                         "resize to %d.\n",
504                         *height);
505         }
506
507         return 0;
508 }
509
510 /*!
511  * start the viewfinder job
512  *
513  * @param cam      structure cam_data *
514  *
515  * @return status  0 Success
516  */
517 static int start_preview(cam_data *cam)
518 {
519         int err = 0;
520
521         pr_debug("MVC: start_preview\n");
522
523 #if defined(CONFIG_MXC_IPU_PRP_VF_SDC) || defined(CONFIG_MXC_IPU_PRP_VF_SDC_MODULE)
524         pr_debug("   This is an SDC display\n");
525         if (cam->output == 0 || cam->output == 2) {
526                 if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
527                         err = prp_vf_sdc_select(cam);
528                 else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
529                         err = prp_vf_sdc_select_bg(cam);
530                 if (err != 0)
531                         return err;
532
533                 err = cam->vf_start_sdc(cam);
534         }
535 #endif
536
537 #if defined(CONFIG_MXC_IPU_PRP_VF_ADC) || defined(CONFIG_MXC_IPU_PRP_VF_ADC_MODULE)
538         pr_debug("   This is an ADC display\n");
539         if (cam->output == 1) {
540                 err = prp_vf_adc_select(cam);
541                 if (err != 0)
542                         return err;
543
544                 err = cam->vf_start_adc(cam);
545         }
546 #endif
547
548         pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
549                  __func__,
550                  cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
551         pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
552                  __func__,
553                  cam->crop_bounds.width, cam->crop_bounds.height);
554         pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
555                  __func__,
556                  cam->crop_defrect.width, cam->crop_defrect.height);
557         pr_debug("End of %s: crop_current widthxheight %d x %d\n",
558                  __func__,
559                  cam->crop_current.width, cam->crop_current.height);
560
561         return err;
562 }
563
564 /*!
565  * shut down the viewfinder job
566  *
567  * @param cam      structure cam_data *
568  *
569  * @return status  0 Success
570  */
571 static int stop_preview(cam_data *cam)
572 {
573         int err = 0;
574
575         pr_debug("MVC: stop preview\n");
576
577 #if defined(CONFIG_MXC_IPU_PRP_VF_ADC) || defined(CONFIG_MXC_IPU_PRP_VF_ADC_MODULE)
578         if (cam->output == 1) {
579                 err = prp_vf_adc_deselect(cam);
580         }
581 #endif
582
583 #if defined(CONFIG_MXC_IPU_PRP_VF_SDC) || defined(CONFIG_MXC_IPU_PRP_VF_SDC_MODULE)
584         if (cam->output == 0 || cam->output == 2) {
585                 if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
586                         err = prp_vf_sdc_deselect(cam);
587                 else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
588                         err = prp_vf_sdc_deselect_bg(cam);
589         }
590 #endif
591
592         return err;
593 }
594
595 /***************************************************************************
596  * VIDIOC Functions.
597  **************************************************************************/
598
599 /*!
600  * V4L2 - mxc_v4l2_g_fmt function
601  *
602  * @param cam         structure cam_data *
603  *
604  * @param f           structure v4l2_format *
605  *
606  * @return  status    0 success, EINVAL failed
607  */
608 static int mxc_v4l2_g_fmt(cam_data *cam, struct v4l2_format *f)
609 {
610         int retval = 0;
611
612         pr_debug("In MVC: mxc_v4l2_g_fmt type=%d\n", f->type);
613
614         switch (f->type) {
615         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
616                 pr_debug("   type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
617                 f->fmt.pix = cam->v2f.fmt.pix;
618                 break;
619         case V4L2_BUF_TYPE_VIDEO_OVERLAY:
620                 pr_debug("   type is V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
621                 f->fmt.win = cam->win;
622                 break;
623         default:
624                 pr_debug("   type is invalid\n");
625                 retval = -EINVAL;
626         }
627
628         pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
629                  __func__,
630                  cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
631         pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
632                  __func__,
633                  cam->crop_bounds.width, cam->crop_bounds.height);
634         pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
635                  __func__,
636                  cam->crop_defrect.width, cam->crop_defrect.height);
637         pr_debug("End of %s: crop_current widthxheight %d x %d\n",
638                  __func__,
639                  cam->crop_current.width, cam->crop_current.height);
640
641         return retval;
642 }
643
644 /*!
645  * V4L2 - mxc_v4l2_s_fmt function
646  *
647  * @param cam         structure cam_data *
648  *
649  * @param f           structure v4l2_format *
650  *
651  * @return  status    0 success, EINVAL failed
652  */
653 static int mxc_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
654 {
655         int retval = 0;
656         int size = 0;
657         int bytesperline = 0;
658         int *width, *height;
659
660         pr_debug("In MVC: mxc_v4l2_s_fmt\n");
661
662         switch (f->type) {
663         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
664                 pr_debug("   type=V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
665                 if (!valid_mode(f->fmt.pix.pixelformat)) {
666                         pr_err("ERROR: v4l2 capture: mxc_v4l2_s_fmt: format "
667                                "not supported\n");
668                         return -EINVAL;
669                 }
670
671                 /*
672                  * Force the capture window resolution to be crop bounds
673                  * for CSI MEM input mode.
674                  */
675                 if (strcmp(mxc_capture_inputs[cam->current_input].name,
676                            "CSI MEM") == 0) {
677                         f->fmt.pix.width = cam->crop_current.width;
678                         f->fmt.pix.height = cam->crop_current.height;
679                 }
680
681                 if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
682                         height = &f->fmt.pix.width;
683                         width = &f->fmt.pix.height;
684                 } else {
685                         width = &f->fmt.pix.width;
686                         height = &f->fmt.pix.height;
687                 }
688
689                 /* stride line limitation */
690                 *width -= *width % 8;
691                 *height -= *height % 8;
692
693                 if ((cam->crop_current.width / *width > 8) ||
694                     ((cam->crop_current.width / *width == 8) &&
695                      (cam->crop_current.width % *width))) {
696                         *width = cam->crop_current.width / 8;
697                         if (*width % 8)
698                                 *width += 8 - *width % 8;
699                         pr_err("ERROR: v4l2 capture: width exceeds limit "
700                                 "resize to %d.\n",
701                                *width);
702                 }
703
704                 if ((cam->crop_current.height / *height > 8) ||
705                     ((cam->crop_current.height / *height == 8) &&
706                      (cam->crop_current.height % *height))) {
707                         *height = cam->crop_current.height / 8;
708                         if (*height % 8)
709                                 *height += 8 - *height % 8;
710                         pr_err("ERROR: v4l2 capture: height exceeds limit "
711                                "resize to %d.\n",
712                                *height);
713                 }
714
715                 switch (f->fmt.pix.pixelformat) {
716                 case V4L2_PIX_FMT_RGB565:
717                         size = f->fmt.pix.width * f->fmt.pix.height * 2;
718                         bytesperline = f->fmt.pix.width * 2;
719                         break;
720                 case V4L2_PIX_FMT_BGR24:
721                         size = f->fmt.pix.width * f->fmt.pix.height * 3;
722                         bytesperline = f->fmt.pix.width * 3;
723                         break;
724                 case V4L2_PIX_FMT_RGB24:
725                         size = f->fmt.pix.width * f->fmt.pix.height * 3;
726                         bytesperline = f->fmt.pix.width * 3;
727                         break;
728                 case V4L2_PIX_FMT_BGR32:
729                         size = f->fmt.pix.width * f->fmt.pix.height * 4;
730                         bytesperline = f->fmt.pix.width * 4;
731                         break;
732                 case V4L2_PIX_FMT_RGB32:
733                         size = f->fmt.pix.width * f->fmt.pix.height * 4;
734                         bytesperline = f->fmt.pix.width * 4;
735                         break;
736                 case V4L2_PIX_FMT_YUV422P:
737                         size = f->fmt.pix.width * f->fmt.pix.height * 2;
738                         bytesperline = f->fmt.pix.width;
739                         break;
740                 case V4L2_PIX_FMT_UYVY:
741                         size = f->fmt.pix.width * f->fmt.pix.height * 2;
742                         bytesperline = f->fmt.pix.width * 2;
743                         break;
744                 case V4L2_PIX_FMT_YUV420:
745                         size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
746                         bytesperline = f->fmt.pix.width;
747                         break;
748                 case V4L2_PIX_FMT_NV12:
749                         size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
750                         bytesperline = f->fmt.pix.width;
751                         break;
752                 default:
753                         break;
754                 }
755
756                 if (f->fmt.pix.bytesperline < bytesperline) {
757                         f->fmt.pix.bytesperline = bytesperline;
758                 } else {
759                         bytesperline = f->fmt.pix.bytesperline;
760                 }
761
762                 if (f->fmt.pix.sizeimage < size) {
763                         f->fmt.pix.sizeimage = size;
764                 } else {
765                         size = f->fmt.pix.sizeimage;
766                 }
767
768                 cam->v2f.fmt.pix = f->fmt.pix;
769
770                 if (cam->v2f.fmt.pix.priv != 0) {
771                         if (copy_from_user(&cam->offset,
772                                            (void *)cam->v2f.fmt.pix.priv,
773                                            sizeof(cam->offset))) {
774                                 retval = -EFAULT;
775                                 break;
776                         }
777                 }
778                 break;
779         case V4L2_BUF_TYPE_VIDEO_OVERLAY:
780                 pr_debug("   type=V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
781                 retval = verify_preview(cam, &f->fmt.win);
782                 cam->win = f->fmt.win;
783                 break;
784         default:
785                 retval = -EINVAL;
786         }
787
788         pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
789                  __func__,
790                  cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
791         pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
792                  __func__,
793                  cam->crop_bounds.width, cam->crop_bounds.height);
794         pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
795                  __func__,
796                  cam->crop_defrect.width, cam->crop_defrect.height);
797         pr_debug("End of %s: crop_current widthxheight %d x %d\n",
798                  __func__,
799                  cam->crop_current.width, cam->crop_current.height);
800
801         return retval;
802 }
803
804 /*!
805  * get control param
806  *
807  * @param cam         structure cam_data *
808  *
809  * @param c           structure v4l2_control *
810  *
811  * @return  status    0 success, EINVAL failed
812  */
813 static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
814 {
815         int status = 0;
816
817         pr_debug("In MVC:mxc_v4l2_g_ctrl\n");
818
819         /* probably don't need to store the values that can be retrieved,
820          * locally, but they are for now. */
821         switch (c->id) {
822         case V4L2_CID_HFLIP:
823                 /* This is handled in the ipu. */
824                 if (cam->rotation == IPU_ROTATE_HORIZ_FLIP)
825                         c->value = 1;
826                 break;
827         case V4L2_CID_VFLIP:
828                 /* This is handled in the ipu. */
829                 if (cam->rotation == IPU_ROTATE_VERT_FLIP)
830                         c->value = 1;
831                 break;
832         case V4L2_CID_MXC_ROT:
833                 /* This is handled in the ipu. */
834                 c->value = cam->rotation;
835                 break;
836         case V4L2_CID_BRIGHTNESS:
837                 c->value = cam->bright;
838                 status = vidioc_int_g_ctrl(cam->sensor, c);
839                 cam->bright = c->value;
840                 break;
841         case V4L2_CID_HUE:
842                 c->value = cam->hue;
843                 status = vidioc_int_g_ctrl(cam->sensor, c);
844                 cam->hue = c->value;
845                 break;
846         case V4L2_CID_CONTRAST:
847                 c->value = cam->contrast;
848                 status = vidioc_int_g_ctrl(cam->sensor, c);
849                 cam->contrast = c->value;
850                 break;
851         case V4L2_CID_SATURATION:
852                 c->value = cam->saturation;
853                 status = vidioc_int_g_ctrl(cam->sensor, c);
854                 cam->saturation = c->value;
855                 break;
856         case V4L2_CID_RED_BALANCE:
857                 c->value = cam->red;
858                 status = vidioc_int_g_ctrl(cam->sensor, c);
859                 cam->red = c->value;
860                 break;
861         case V4L2_CID_BLUE_BALANCE:
862                 c->value = cam->blue;
863                 status = vidioc_int_g_ctrl(cam->sensor, c);
864                 cam->blue = c->value;
865                 break;
866         case V4L2_CID_BLACK_LEVEL:
867                 c->value = cam->ae_mode;
868                 status = vidioc_int_g_ctrl(cam->sensor, c);
869                 cam->ae_mode = c->value;
870                 break;
871         default:
872                 status = vidioc_int_g_ctrl(cam->sensor, c);
873         }
874
875         return status;
876 }
877
878 /*!
879  * V4L2 - set_control function
880  *          V4L2_CID_PRIVATE_BASE is the extention for IPU preprocessing.
881  *          0 for normal operation
882  *          1 for vertical flip
883  *          2 for horizontal flip
884  *          3 for horizontal and vertical flip
885  *          4 for 90 degree rotation
886  * @param cam         structure cam_data *
887  *
888  * @param c           structure v4l2_control *
889  *
890  * @return  status    0 success, EINVAL failed
891  */
892 static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
893 {
894         int ret = 0;
895         int tmp_rotation = IPU_ROTATE_NONE;
896
897         pr_debug("In MVC:mxc_v4l2_s_ctrl\n");
898
899         switch (c->id) {
900         case V4L2_CID_HFLIP:
901                 /* This is done by the IPU */
902                 if (c->value == 1) {
903                         if ((cam->rotation != IPU_ROTATE_VERT_FLIP) &&
904                             (cam->rotation != IPU_ROTATE_180))
905                                 cam->rotation = IPU_ROTATE_HORIZ_FLIP;
906                         else
907                                 cam->rotation = IPU_ROTATE_180;
908                 } else {
909                         if (cam->rotation == IPU_ROTATE_HORIZ_FLIP)
910                                 cam->rotation = IPU_ROTATE_NONE;
911                         if (cam->rotation == IPU_ROTATE_180)
912                                 cam->rotation = IPU_ROTATE_VERT_FLIP;
913                 }
914                 break;
915         case V4L2_CID_VFLIP:
916                 /* This is done by the IPU */
917                 if (c->value == 1) {
918                         if ((cam->rotation != IPU_ROTATE_HORIZ_FLIP) &&
919                             (cam->rotation != IPU_ROTATE_180))
920                                 cam->rotation = IPU_ROTATE_VERT_FLIP;
921                         else
922                                 cam->rotation = IPU_ROTATE_180;
923                 } else {
924                         if (cam->rotation == IPU_ROTATE_VERT_FLIP)
925                                 cam->rotation = IPU_ROTATE_NONE;
926                         if (cam->rotation == IPU_ROTATE_180)
927                                 cam->rotation = IPU_ROTATE_HORIZ_FLIP;
928                 }
929                 break;
930         case V4L2_CID_MXC_ROT:
931         case V4L2_CID_MXC_VF_ROT:
932                 /* This is done by the IPU */
933                 switch (c->value) {
934                 case V4L2_MXC_ROTATE_NONE:
935                         tmp_rotation = IPU_ROTATE_NONE;
936                         break;
937                 case V4L2_MXC_ROTATE_VERT_FLIP:
938                         tmp_rotation = IPU_ROTATE_VERT_FLIP;
939                         break;
940                 case V4L2_MXC_ROTATE_HORIZ_FLIP:
941                         tmp_rotation = IPU_ROTATE_HORIZ_FLIP;
942                         break;
943                 case V4L2_MXC_ROTATE_180:
944                         tmp_rotation = IPU_ROTATE_180;
945                         break;
946                 case V4L2_MXC_ROTATE_90_RIGHT:
947                         tmp_rotation = IPU_ROTATE_90_RIGHT;
948                         break;
949                 case V4L2_MXC_ROTATE_90_RIGHT_VFLIP:
950                         tmp_rotation = IPU_ROTATE_90_RIGHT_VFLIP;
951                         break;
952                 case V4L2_MXC_ROTATE_90_RIGHT_HFLIP:
953                         tmp_rotation = IPU_ROTATE_90_RIGHT_HFLIP;
954                         break;
955                 case V4L2_MXC_ROTATE_90_LEFT:
956                         tmp_rotation = IPU_ROTATE_90_LEFT;
957                         break;
958                 default:
959                         ret = -EINVAL;
960                 }
961
962                 if (c->id == V4L2_CID_MXC_VF_ROT)
963                         cam->vf_rotation = tmp_rotation;
964                 else
965                         cam->rotation = tmp_rotation;
966
967                 break;
968         case V4L2_CID_HUE:
969                 cam->hue = c->value;
970                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true);
971                 ret = vidioc_int_s_ctrl(cam->sensor, c);
972                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false);
973                 break;
974         case V4L2_CID_CONTRAST:
975                 cam->contrast = c->value;
976                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true);
977                 ret = vidioc_int_s_ctrl(cam->sensor, c);
978                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false);
979                 break;
980         case V4L2_CID_BRIGHTNESS:
981                 cam->bright = c->value;
982                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true);
983                 ret = vidioc_int_s_ctrl(cam->sensor, c);
984                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false);
985                 break;
986         case V4L2_CID_SATURATION:
987                 cam->saturation = c->value;
988                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true);
989                 ret = vidioc_int_s_ctrl(cam->sensor, c);
990                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false);
991                 break;
992         case V4L2_CID_RED_BALANCE:
993                 cam->red = c->value;
994                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true);
995                 ret = vidioc_int_s_ctrl(cam->sensor, c);
996                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false);
997                 break;
998         case V4L2_CID_BLUE_BALANCE:
999                 cam->blue = c->value;
1000                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true);
1001                 ret = vidioc_int_s_ctrl(cam->sensor, c);
1002                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false);
1003                 break;
1004         case V4L2_CID_EXPOSURE:
1005                 cam->ae_mode = c->value;
1006                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true);
1007                 ret = vidioc_int_s_ctrl(cam->sensor, c);
1008                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false);
1009                 break;
1010         case V4L2_CID_MXC_FLASH:
1011 #ifdef CONFIG_MXC_IPU_V1
1012                 ipu_csi_flash_strobe(true);
1013 #endif
1014                 break;
1015         default:
1016                 pr_debug("   default case\n");
1017                 ret = -EINVAL;
1018                 break;
1019         }
1020
1021         return ret;
1022 }
1023
1024 /*!
1025  * V4L2 - mxc_v4l2_s_param function
1026  * Allows setting of capturemode and frame rate.
1027  *
1028  * @param cam         structure cam_data *
1029  * @param parm        structure v4l2_streamparm *
1030  *
1031  * @return  status    0 success, EINVAL failed
1032  */
1033 static int mxc_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
1034 {
1035         struct v4l2_ifparm ifparm;
1036         struct v4l2_format cam_fmt;
1037         struct v4l2_streamparm currentparm;
1038         ipu_csi_signal_cfg_t csi_param;
1039         int err = 0;
1040
1041         pr_debug("In mxc_v4l2_s_param\n");
1042
1043         if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1044                 pr_err(KERN_ERR "mxc_v4l2_s_param invalid type\n");
1045                 return -EINVAL;
1046         }
1047
1048         /* Stop the viewfinder */
1049         if (cam->overlay_on == true) {
1050                 stop_preview(cam);
1051         }
1052
1053         currentparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1054
1055         /* First check that this device can support the changes requested. */
1056         err = vidioc_int_g_parm(cam->sensor, &currentparm);
1057         if (err) {
1058                 pr_err("%s: vidioc_int_g_parm returned an error %d\n",
1059                         __func__, err);
1060                 goto exit;
1061         }
1062
1063         pr_debug("   Current capabilities are %x\n",
1064                         currentparm.parm.capture.capability);
1065         pr_debug("   Current capturemode is %d  change to %d\n",
1066                         currentparm.parm.capture.capturemode,
1067                         parm->parm.capture.capturemode);
1068         pr_debug("   Current framerate is %d  change to %d\n",
1069                         currentparm.parm.capture.timeperframe.denominator,
1070                         parm->parm.capture.timeperframe.denominator);
1071
1072         /* This will change any camera settings needed. */
1073         ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true);
1074         err = vidioc_int_s_parm(cam->sensor, parm);
1075         ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false);
1076         if (err) {
1077                 pr_err("%s: vidioc_int_s_parm returned an error %d\n",
1078                         __func__, err);
1079                 goto exit;
1080         }
1081
1082         /* If resolution changed, need to re-program the CSI */
1083         /* Get new values. */
1084         vidioc_int_g_ifparm(cam->sensor, &ifparm);
1085
1086         csi_param.data_width = 0;
1087         csi_param.clk_mode = 0;
1088         csi_param.ext_vsync = 0;
1089         csi_param.Vsync_pol = 0;
1090         csi_param.Hsync_pol = 0;
1091         csi_param.pixclk_pol = 0;
1092         csi_param.data_pol = 0;
1093         csi_param.sens_clksrc = 0;
1094         csi_param.pack_tight = 0;
1095         csi_param.force_eof = 0;
1096         csi_param.data_en_pol = 0;
1097         csi_param.data_fmt = 0;
1098         csi_param.csi = 0;
1099         csi_param.mclk = 0;
1100
1101         /* This may not work on other platforms. Check when adding a new one.*/
1102         pr_debug("   clock_curr=mclk=%d\n", ifparm.u.bt656.clock_curr);
1103         if (ifparm.u.bt656.clock_curr == 0) {
1104                 csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE;
1105         } else {
1106                 csi_param.clk_mode = IPU_CSI_CLK_MODE_GATED_CLK;
1107         }
1108
1109         csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;
1110
1111         if (ifparm.u.bt656.mode == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT) {
1112                 csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
1113         } else if (ifparm.u.bt656.mode
1114                                 == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT) {
1115                 csi_param.data_width = IPU_CSI_DATA_WIDTH_10;
1116         } else {
1117                 csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
1118         }
1119
1120         csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;
1121         csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;
1122         csi_param.ext_vsync = ifparm.u.bt656.bt_sync_correct;
1123
1124         /* if the capturemode changed, the size bounds will have changed. */
1125         cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1126         vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
1127         pr_debug("   g_fmt_cap returns widthxheight of input as %d x %d\n",
1128                         cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
1129
1130         csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat;
1131
1132         cam->crop_bounds.top = cam->crop_bounds.left = 0;
1133         cam->crop_bounds.width = cam_fmt.fmt.pix.width;
1134         cam->crop_bounds.height = cam_fmt.fmt.pix.height;
1135
1136         /*
1137          * Set the default current cropped resolution to be the same with
1138          * the cropping boundary.
1139          */
1140         cam->crop_current.width = cam->crop_bounds.width;
1141         cam->crop_current.height = cam->crop_bounds.height;
1142
1143         /* This essentially loses the data at the left and bottom of the image
1144          * giving a digital zoom image, if crop_current is less than the full
1145          * size of the image. */
1146         ipu_csi_set_window_size(cam->crop_current.width,
1147                                 cam->crop_current.height, cam->csi);
1148         ipu_csi_set_window_pos(cam->crop_current.left,
1149                                cam->crop_current.top,
1150                                cam->csi);
1151         ipu_csi_init_interface(cam->crop_bounds.width,
1152                                cam->crop_bounds.height,
1153                                cam_fmt.fmt.pix.pixelformat, csi_param);
1154
1155
1156 exit:
1157         if (cam->overlay_on == true)
1158                 start_preview(cam);
1159
1160         return err;
1161 }
1162
1163 /*!
1164  * V4L2 - mxc_v4l2_s_std function
1165  *
1166  * Sets the TV standard to be used.
1167  *
1168  * @param cam         structure cam_data *
1169  * @param parm        structure v4l2_streamparm *
1170  *
1171  * @return  status    0 success, EINVAL failed
1172  */
1173 static int mxc_v4l2_s_std(cam_data *cam, v4l2_std_id e)
1174 {
1175         bool change = false;
1176
1177         if (e != cam->standard.id) {
1178                 change = true;
1179         }
1180
1181         pr_debug("In mxc_v4l2_s_std %Lx\n", e);
1182         if (e == V4L2_STD_PAL) {
1183                 pr_debug("   Setting standard to PAL %Lx\n", V4L2_STD_PAL);
1184                 cam->standard.id = V4L2_STD_PAL;
1185                 video_index = TV_PAL;
1186                 cam->crop_current.top = 0;
1187         } else if (e == V4L2_STD_NTSC) {
1188                 pr_debug("   Setting standard to NTSC %Lx\n",
1189                                 V4L2_STD_NTSC);
1190                 /* Get rid of the white dot line in NTSC signal input */
1191                 cam->standard.id = V4L2_STD_NTSC;
1192                 video_index = TV_NTSC;
1193                 cam->crop_current.top = 12;
1194         } else {
1195                 cam->standard.id = V4L2_STD_ALL;
1196                 video_index = TV_NOT_LOCKED;
1197                 cam->crop_current.top = 0;
1198                 pr_err("ERROR: unrecognized std! %Lx (PAL=%Lx, NTSC=%Lx\n",
1199                         e, V4L2_STD_PAL, V4L2_STD_NTSC);
1200         }
1201
1202         cam->standard.index = video_index;
1203         strcpy(cam->standard.name, video_fmts[video_index].name);
1204         cam->crop_bounds.width = video_fmts[video_index].raw_width;
1205         cam->crop_bounds.height = video_fmts[video_index].raw_height;
1206         cam->crop_current.width = video_fmts[video_index].active_width;
1207         cam->crop_current.height = video_fmts[video_index].active_height;
1208         cam->crop_current.left = 0;
1209
1210         return 0;
1211 }
1212
1213 /*!
1214  * V4L2 - mxc_v4l2_g_std function
1215  *
1216  * Gets the TV standard from the TV input device.
1217  *
1218  * @param cam         structure cam_data *
1219  *
1220  * @param e           structure v4l2_streamparm *
1221  *
1222  * @return  status    0 success, EINVAL failed
1223  */
1224 static int mxc_v4l2_g_std(cam_data *cam, v4l2_std_id *e)
1225 {
1226         struct v4l2_format tv_fmt;
1227
1228         pr_debug("In mxc_v4l2_g_std\n");
1229
1230         if (cam->device_type == 1) {
1231                 /* Use this function to get what the TV-In device detects the
1232                  * format to be. pixelformat is used to return the std value
1233                  * since the interface has no vidioc_g_std.*/
1234                 tv_fmt.type = V4L2_BUF_TYPE_PRIVATE;
1235                 vidioc_int_g_fmt_cap(cam->sensor, &tv_fmt);
1236
1237                 /* If the TV-in automatically detects the standard, then if it
1238                  * changes, the settings need to change. */
1239                 if (cam->standard_autodetect) {
1240                         if (cam->standard.id != tv_fmt.fmt.pix.pixelformat) {
1241                                 pr_debug("MVC: mxc_v4l2_g_std: "
1242                                         "Changing standard\n");
1243                                 mxc_v4l2_s_std(cam, tv_fmt.fmt.pix.pixelformat);
1244                         }
1245                 }
1246
1247                 *e = tv_fmt.fmt.pix.pixelformat;
1248         }
1249
1250         return 0;
1251 }
1252
1253 /*!
1254  * Dequeue one V4L capture buffer
1255  *
1256  * @param cam         structure cam_data *
1257  * @param buf         structure v4l2_buffer *
1258  *
1259  * @return  status    0 success, EINVAL invalid frame number,
1260  *                    ETIME timeout, ERESTARTSYS interrupted by user
1261  */
1262 static int mxc_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
1263 {
1264         int retval = 0;
1265         struct mxc_v4l_frame *frame;
1266
1267         pr_debug("In MVC:mxc_v4l_dqueue\n");
1268
1269         if (!wait_event_interruptible_timeout(cam->enc_queue,
1270                                               cam->enc_counter != 0, 10 * HZ)) {
1271                 pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue timeout "
1272                         "enc_counter %x\n",
1273                        cam->enc_counter);
1274                 return -ETIME;
1275         } else if (signal_pending(current)) {
1276                 pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue() "
1277                         "interrupt received\n");
1278                 return -ERESTARTSYS;
1279         }
1280
1281         cam->enc_counter--;
1282
1283         frame = list_entry(cam->done_q.next, struct mxc_v4l_frame, queue);
1284         list_del(cam->done_q.next);
1285         if (frame->buffer.flags & V4L2_BUF_FLAG_DONE) {
1286                 frame->buffer.flags &= ~V4L2_BUF_FLAG_DONE;
1287         } else if (frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
1288                 pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
1289                         "Buffer not filled.\n");
1290                 frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
1291                 retval = -EINVAL;
1292         } else if ((frame->buffer.flags & 0x7) == V4L2_BUF_FLAG_MAPPED) {
1293                 pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
1294                         "Buffer not queued.\n");
1295                 retval = -EINVAL;
1296         }
1297
1298         buf->bytesused = cam->v2f.fmt.pix.sizeimage;
1299         buf->index = frame->index;
1300         buf->flags = frame->buffer.flags;
1301         buf->m = cam->frame[frame->index].buffer.m;
1302
1303         return retval;
1304 }
1305
1306 /*!
1307  * V4L interface - open function
1308  *
1309  * @param inode        structure inode *
1310  * @param file         structure file *
1311  *
1312  * @return  status    0 success, ENODEV invalid device instance,
1313  *                    ENODEV timeout, ERESTARTSYS interrupted by user
1314  */
1315 static int mxc_v4l_open(struct inode *inode, struct file *file)
1316 {
1317         struct v4l2_ifparm ifparm;
1318         struct v4l2_format cam_fmt;
1319         ipu_csi_signal_cfg_t csi_param;
1320         struct video_device *dev = video_devdata(file);
1321         cam_data *cam = video_get_drvdata(dev);
1322         int err = 0;
1323
1324         pr_debug("\nIn MVC: mxc_v4l_open\n");
1325         pr_debug("   device name is %s\n", dev->name);
1326
1327         if (!cam) {
1328                 pr_err("ERROR: v4l2 capture: Internal error, "
1329                         "cam_data not found!\n");
1330                 return -EBADF;
1331         }
1332
1333         down(&cam->busy_lock);
1334         err = 0;
1335         if (signal_pending(current))
1336                 goto oops;
1337
1338         if (cam->open_count++ == 0) {
1339                 wait_event_interruptible(cam->power_queue,
1340                                          cam->low_power == false);
1341
1342                 if (strcmp(mxc_capture_inputs[cam->current_input].name,
1343                            "CSI MEM") == 0) {
1344 #if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
1345                         err = csi_enc_select(cam);
1346 #endif
1347                 } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
1348                                   "CSI IC MEM") == 0) {
1349 #if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
1350                         err = prp_enc_select(cam);
1351 #endif
1352                 }
1353
1354                 cam->enc_counter = 0;
1355                 cam->skip_frame = 0;
1356                 INIT_LIST_HEAD(&cam->ready_q);
1357                 INIT_LIST_HEAD(&cam->working_q);
1358                 INIT_LIST_HEAD(&cam->done_q);
1359
1360                 vidioc_int_g_ifparm(cam->sensor, &ifparm);
1361
1362                 csi_param.sens_clksrc = 0;
1363
1364                 csi_param.clk_mode = 0;
1365                 csi_param.data_pol = 0;
1366                 csi_param.ext_vsync = 0;
1367
1368                 csi_param.pack_tight = 0;
1369                 csi_param.force_eof = 0;
1370                 csi_param.data_en_pol = 0;
1371                 csi_param.mclk = ifparm.u.bt656.clock_curr;
1372
1373                 csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;
1374
1375                 /* Once we handle multiple inputs this will need to change. */
1376                 csi_param.csi = 0;
1377
1378                 if (ifparm.u.bt656.mode
1379                                 == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT)
1380                         csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
1381                 else if (ifparm.u.bt656.mode
1382                                 == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT)
1383                         csi_param.data_width = IPU_CSI_DATA_WIDTH_10;
1384                 else
1385                         csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
1386
1387
1388                 csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;
1389                 csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;
1390
1391                 csi_param.csi = cam->csi;
1392
1393                 cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1394                 vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
1395
1396                 /* Reset the sizes.  Needed to prevent carryover of last
1397                  * operation.*/
1398                 cam->crop_bounds.top = cam->crop_bounds.left = 0;
1399                 cam->crop_bounds.width = cam_fmt.fmt.pix.width;
1400                 cam->crop_bounds.height = cam_fmt.fmt.pix.height;
1401
1402                 /* This also is the max crop size for this device. */
1403                 cam->crop_defrect.top = cam->crop_defrect.left = 0;
1404                 cam->crop_defrect.width = cam_fmt.fmt.pix.width;
1405                 cam->crop_defrect.height = cam_fmt.fmt.pix.height;
1406
1407                 /* At this point, this is also the current image size. */
1408                 cam->crop_current.top = cam->crop_current.left = 0;
1409                 cam->crop_current.width = cam_fmt.fmt.pix.width;
1410                 cam->crop_current.height = cam_fmt.fmt.pix.height;
1411
1412                 pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
1413                         __func__,
1414                         cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
1415                 pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
1416                         __func__,
1417                         cam->crop_bounds.width, cam->crop_bounds.height);
1418                 pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
1419                         __func__,
1420                         cam->crop_defrect.width, cam->crop_defrect.height);
1421                 pr_debug("End of %s: crop_current widthxheight %d x %d\n",
1422                         __func__,
1423                         cam->crop_current.width, cam->crop_current.height);
1424
1425                 csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat;
1426                 pr_debug("On Open: Input to ipu size is %d x %d\n",
1427                                 cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
1428                 ipu_csi_set_window_size(cam->crop_current.width,
1429                                         cam->crop_current.width,
1430                                         cam->csi);
1431                 ipu_csi_set_window_pos(cam->crop_current.left,
1432                                         cam->crop_current.top,
1433                                         cam->csi);
1434                 ipu_csi_init_interface(cam->crop_bounds.width,
1435                                         cam->crop_bounds.height,
1436                                         cam_fmt.fmt.pix.pixelformat,
1437                                         csi_param);
1438
1439                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi,
1440                                        true, true);
1441                 vidioc_int_init(cam->sensor);
1442
1443                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi,
1444                                        false, false);
1445 }
1446
1447         file->private_data = dev;
1448
1449       oops:
1450         up(&cam->busy_lock);
1451         return err;
1452 }
1453
1454 /*!
1455  * V4L interface - close function
1456  *
1457  * @param inode    struct inode *
1458  * @param file     struct file *
1459  *
1460  * @return         0 success
1461  */
1462 static int mxc_v4l_close(struct inode *inode, struct file *file)
1463 {
1464         struct video_device *dev = video_devdata(file);
1465         int err = 0;
1466         cam_data *cam = video_get_drvdata(dev);
1467
1468         pr_debug("In MVC:mxc_v4l_close\n");
1469
1470         if (!cam) {
1471                 pr_err("ERROR: v4l2 capture: Internal error, "
1472                         "cam_data not found!\n");
1473                 return -EBADF;
1474         }
1475
1476         /* for the case somebody hit the ctrl C */
1477         if (cam->overlay_pid == current->pid) {
1478                 err = stop_preview(cam);
1479                 cam->overlay_on = false;
1480         }
1481         if (cam->capture_pid == current->pid) {
1482                 err |= mxc_streamoff(cam);
1483                 wake_up_interruptible(&cam->enc_queue);
1484         }
1485
1486         if (--cam->open_count == 0) {
1487                 wait_event_interruptible(cam->power_queue,
1488                                          cam->low_power == false);
1489                 pr_info("mxc_v4l_close: release resource\n");
1490
1491                 if (strcmp(mxc_capture_inputs[cam->current_input].name,
1492                            "CSI MEM") == 0) {
1493 #if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
1494                         err |= csi_enc_deselect(cam);
1495 #endif
1496                 } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
1497                                   "CSI IC MEM") == 0) {
1498 #if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
1499                         err |= prp_enc_deselect(cam);
1500 #endif
1501                 }
1502
1503                 mxc_free_frame_buf(cam);
1504                 file->private_data = NULL;
1505
1506                 /* capture off */
1507                 wake_up_interruptible(&cam->enc_queue);
1508                 mxc_free_frames(cam);
1509                 cam->enc_counter++;
1510         }
1511
1512         return err;
1513 }
1514
1515 #if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC) || \
1516     defined(CONFIG_MXC_IPU_PRP_ENC_MODULE) || \
1517     defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
1518 /*
1519  * V4L interface - read function
1520  *
1521  * @param file       struct file *
1522  * @param read buf   char *
1523  * @param count      size_t
1524  * @param ppos       structure loff_t *
1525  *
1526  * @return           bytes read
1527  */
1528 static ssize_t mxc_v4l_read(struct file *file, char *buf, size_t count,
1529                             loff_t *ppos)
1530 {
1531         int err = 0;
1532         u8 *v_address;
1533         struct video_device *dev = video_devdata(file);
1534         cam_data *cam = video_get_drvdata(dev);
1535
1536         if (down_interruptible(&cam->busy_lock))
1537                 return -EINTR;
1538
1539         /* Stop the viewfinder */
1540         if (cam->overlay_on == true)
1541                 stop_preview(cam);
1542
1543         v_address = dma_alloc_coherent(0,
1544                                        PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
1545                                        &cam->still_buf, GFP_DMA | GFP_KERNEL);
1546
1547         if (!v_address) {
1548                 err = -ENOBUFS;
1549                 goto exit0;
1550         }
1551
1552         err = prp_still_select(cam);
1553         if (err != 0) {
1554                 err = -EIO;
1555                 goto exit1;
1556         }
1557
1558         cam->still_counter = 0;
1559         err = cam->csi_start(cam);
1560         if (err != 0) {
1561                 err = -EIO;
1562                 goto exit2;
1563         }
1564
1565         if (!wait_event_interruptible_timeout(cam->still_queue,
1566                                               cam->still_counter != 0,
1567                                               10 * HZ)) {
1568                 pr_err("ERROR: v4l2 capture: mxc_v4l_read timeout counter %x\n",
1569                        cam->still_counter);
1570                 err = -ETIME;
1571                 goto exit2;
1572         }
1573         err = copy_to_user(buf, v_address, cam->v2f.fmt.pix.sizeimage);
1574
1575       exit2:
1576         prp_still_deselect(cam);
1577
1578       exit1:
1579         dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address,
1580                           cam->still_buf);
1581         cam->still_buf = 0;
1582
1583       exit0:
1584         if (cam->overlay_on == true) {
1585                 start_preview(cam);
1586         }
1587
1588         up(&cam->busy_lock);
1589         if (err < 0)
1590                 return err;
1591
1592         return (cam->v2f.fmt.pix.sizeimage - err);
1593 }
1594 #endif
1595
1596 /*!
1597  * V4L interface - ioctl function
1598  *
1599  * @param inode      struct inode*
1600  *
1601  * @param file       struct file*
1602  *
1603  * @param ioctlnr    unsigned int
1604  *
1605  * @param arg        void*
1606  *
1607  * @return           0 success, ENODEV for invalid device instance,
1608  *                   -1 for other errors.
1609  */
1610 static int mxc_v4l_do_ioctl(struct inode *inode, struct file *file,
1611                             unsigned int ioctlnr, void *arg)
1612 {
1613         struct video_device *dev = video_devdata(file);
1614         cam_data *cam = video_get_drvdata(dev);
1615         int retval = 0;
1616         unsigned long lock_flags;
1617
1618         pr_debug("In MVC: mxc_v4l_do_ioctl %x\n", ioctlnr);
1619         wait_event_interruptible(cam->power_queue, cam->low_power == false);
1620         /* make this _really_ smp-safe */
1621         if (down_interruptible(&cam->busy_lock))
1622                 return -EBUSY;
1623
1624         switch (ioctlnr) {
1625         /*!
1626          * V4l2 VIDIOC_QUERYCAP ioctl
1627          */
1628         case VIDIOC_QUERYCAP: {
1629                 struct v4l2_capability *cap = arg;
1630                 pr_debug("   case VIDIOC_QUERYCAP\n");
1631                 strcpy(cap->driver, "mxc_v4l2");
1632                 cap->version = KERNEL_VERSION(0, 1, 11);
1633                 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1634                                     V4L2_CAP_VIDEO_OVERLAY |
1635                                     V4L2_CAP_STREAMING |
1636                                     V4L2_CAP_READWRITE;
1637                 cap->card[0] = '\0';
1638                 cap->bus_info[0] = '\0';
1639                 break;
1640         }
1641
1642         /*!
1643          * V4l2 VIDIOC_G_FMT ioctl
1644          */
1645         case VIDIOC_G_FMT: {
1646                 struct v4l2_format *gf = arg;
1647                 pr_debug("   case VIDIOC_G_FMT\n");
1648                 retval = mxc_v4l2_g_fmt(cam, gf);
1649                 break;
1650         }
1651
1652         /*!
1653          * V4l2 VIDIOC_S_FMT ioctl
1654          */
1655         case VIDIOC_S_FMT: {
1656                 struct v4l2_format *sf = arg;
1657                 pr_debug("   case VIDIOC_S_FMT\n");
1658                 retval = mxc_v4l2_s_fmt(cam, sf);
1659                 break;
1660         }
1661
1662         /*!
1663          * V4l2 VIDIOC_REQBUFS ioctl
1664          */
1665         case VIDIOC_REQBUFS: {
1666                 struct v4l2_requestbuffers *req = arg;
1667                 pr_debug("   case VIDIOC_REQBUFS\n");
1668
1669                 if (req->count > FRAME_NUM) {
1670                         pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
1671                                "not enough buffers\n");
1672                         req->count = FRAME_NUM;
1673                 }
1674
1675                 if ((req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
1676                     (req->memory != V4L2_MEMORY_MMAP)) {
1677                         pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
1678                                "wrong buffer type\n");
1679                         retval = -EINVAL;
1680                         break;
1681                 }
1682
1683                 mxc_streamoff(cam);
1684                 mxc_free_frame_buf(cam);
1685                 cam->enc_counter = 0;
1686                 cam->skip_frame = 0;
1687                 INIT_LIST_HEAD(&cam->ready_q);
1688                 INIT_LIST_HEAD(&cam->working_q);
1689                 INIT_LIST_HEAD(&cam->done_q);
1690
1691                 retval = mxc_allocate_frame_buf(cam, req->count);
1692                 break;
1693         }
1694
1695         /*!
1696          * V4l2 VIDIOC_QUERYBUF ioctl
1697          */
1698         case VIDIOC_QUERYBUF: {
1699                 struct v4l2_buffer *buf = arg;
1700                 int index = buf->index;
1701                 pr_debug("   case VIDIOC_QUERYBUF\n");
1702
1703                 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1704                         pr_err("ERROR: v4l2 capture: "
1705                                "VIDIOC_QUERYBUFS: "
1706                                "wrong buffer type\n");
1707                         retval = -EINVAL;
1708                         break;
1709                 }
1710
1711                 memset(buf, 0, sizeof(buf));
1712                 buf->index = index;
1713
1714                 down(&cam->param_lock);
1715                 retval = mxc_v4l2_buffer_status(cam, buf);
1716                 up(&cam->param_lock);
1717                 break;
1718         }
1719
1720         /*!
1721          * V4l2 VIDIOC_QBUF ioctl
1722          */
1723         case VIDIOC_QBUF: {
1724                 struct v4l2_buffer *buf = arg;
1725                 int index = buf->index;
1726                 pr_debug("   case VIDIOC_QBUF\n");
1727
1728                 spin_lock_irqsave(&cam->int_lock, lock_flags);
1729                 cam->frame[index].buffer.m.offset = buf->m.offset;
1730                 if ((cam->frame[index].buffer.flags & 0x7) ==
1731                     V4L2_BUF_FLAG_MAPPED) {
1732                         cam->frame[index].buffer.flags |=
1733                             V4L2_BUF_FLAG_QUEUED;
1734                         if (cam->skip_frame > 0) {
1735                                 list_add_tail(&cam->frame[index].queue,
1736                                               &cam->working_q);
1737                                 retval =
1738                                     cam->enc_update_eba(cam->
1739                                                         frame[index].
1740                                                         buffer.m.offset,
1741                                                         &cam->
1742                                                         ping_pong_csi);
1743                                 cam->skip_frame = 0;
1744                         } else {
1745                                 list_add_tail(&cam->frame[index].queue,
1746                                               &cam->ready_q);
1747                         }
1748                 } else if (cam->frame[index].buffer.
1749                            flags & V4L2_BUF_FLAG_QUEUED) {
1750                         pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
1751                                "buffer already queued\n");
1752                         retval = -EINVAL;
1753                 } else if (cam->frame[index].buffer.
1754                            flags & V4L2_BUF_FLAG_DONE) {
1755                         pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
1756                                "overwrite done buffer.\n");
1757                         cam->frame[index].buffer.flags &=
1758                             ~V4L2_BUF_FLAG_DONE;
1759                         cam->frame[index].buffer.flags |=
1760                             V4L2_BUF_FLAG_QUEUED;
1761                         retval = -EINVAL;
1762                 }
1763
1764                 buf->flags = cam->frame[index].buffer.flags;
1765                 spin_unlock_irqrestore(&cam->int_lock, lock_flags);
1766                 break;
1767         }
1768
1769         /*!
1770          * V4l2 VIDIOC_DQBUF ioctl
1771          */
1772         case VIDIOC_DQBUF: {
1773                 struct v4l2_buffer *buf = arg;
1774                 pr_debug("   case VIDIOC_DQBUF\n");
1775
1776                 if ((cam->enc_counter == 0) &&
1777                         (file->f_flags & O_NONBLOCK)) {
1778                         retval = -EAGAIN;
1779                         break;
1780                 }
1781
1782                 retval = mxc_v4l_dqueue(cam, buf);
1783
1784                 break;
1785         }
1786
1787         /*!
1788          * V4l2 VIDIOC_STREAMON ioctl
1789          */
1790         case VIDIOC_STREAMON: {
1791                 pr_debug("   case VIDIOC_STREAMON\n");
1792                 retval = mxc_streamon(cam);
1793                 break;
1794         }
1795
1796         /*!
1797          * V4l2 VIDIOC_STREAMOFF ioctl
1798          */
1799         case VIDIOC_STREAMOFF: {
1800                 pr_debug("   case VIDIOC_STREAMOFF\n");
1801                 retval = mxc_streamoff(cam);
1802                 break;
1803         }
1804
1805         /*!
1806          * V4l2 VIDIOC_G_CTRL ioctl
1807          */
1808         case VIDIOC_G_CTRL: {
1809                 pr_debug("   case VIDIOC_G_CTRL\n");
1810                 retval = mxc_v4l2_g_ctrl(cam, arg);
1811                 break;
1812         }
1813
1814         /*!
1815          * V4l2 VIDIOC_S_CTRL ioctl
1816          */
1817         case VIDIOC_S_CTRL: {
1818                 pr_debug("   case VIDIOC_S_CTRL\n");
1819                 retval = mxc_v4l2_s_ctrl(cam, arg);
1820                 break;
1821         }
1822
1823         /*!
1824          * V4l2 VIDIOC_CROPCAP ioctl
1825          */
1826         case VIDIOC_CROPCAP: {
1827                 struct v4l2_cropcap *cap = arg;
1828                 pr_debug("   case VIDIOC_CROPCAP\n");
1829                 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1830                     cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
1831                         retval = -EINVAL;
1832                         break;
1833                 }
1834                 cap->bounds = cam->crop_bounds;
1835                 cap->defrect = cam->crop_defrect;
1836                 break;
1837         }
1838
1839         /*!
1840          * V4l2 VIDIOC_G_CROP ioctl
1841          */
1842         case VIDIOC_G_CROP: {
1843                 struct v4l2_crop *crop = arg;
1844                 pr_debug("   case VIDIOC_G_CROP\n");
1845
1846                 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1847                     crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
1848                         retval = -EINVAL;
1849                         break;
1850                 }
1851                 crop->c = cam->crop_current;
1852                 break;
1853         }
1854
1855         /*!
1856          * V4l2 VIDIOC_S_CROP ioctl
1857          */
1858         case VIDIOC_S_CROP: {
1859                 struct v4l2_crop *crop = arg;
1860                 struct v4l2_rect *b = &cam->crop_bounds;
1861                 pr_debug("   case VIDIOC_S_CROP\n");
1862
1863                 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1864                     crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
1865                         retval = -EINVAL;
1866                         break;
1867                 }
1868
1869                 crop->c.top = (crop->c.top < b->top) ? b->top
1870                               : crop->c.top;
1871                 if (crop->c.top > b->top + b->height)
1872                         crop->c.top = b->top + b->height - 1;
1873                 if (crop->c.height > b->top + b->height - crop->c.top)
1874                         crop->c.height =
1875                                 b->top + b->height - crop->c.top;
1876
1877                 crop->c.left = (crop->c.left < b->left) ? b->left
1878                     : crop->c.left;
1879                 if (crop->c.left > b->left + b->width)
1880                         crop->c.left = b->left + b->width - 1;
1881                 if (crop->c.width > b->left - crop->c.left + b->width)
1882                         crop->c.width =
1883                                 b->left - crop->c.left + b->width;
1884
1885                 crop->c.width -= crop->c.width % 8;
1886                 crop->c.left -= crop->c.left % 4;
1887                 cam->crop_current = crop->c;
1888
1889                 pr_debug("   Cropping Input to ipu size %d x %d\n",
1890                                 cam->crop_current.width,
1891                                 cam->crop_current.height);
1892                 ipu_csi_set_window_size(cam->crop_current.width,
1893                                         cam->crop_current.height,
1894                                         cam->csi);
1895                 ipu_csi_set_window_pos(cam->crop_current.left,
1896                                        cam->crop_current.top,
1897                                        cam->csi);
1898                 break;
1899         }
1900
1901         /*!
1902          * V4l2 VIDIOC_OVERLAY ioctl
1903          */
1904         case VIDIOC_OVERLAY: {
1905                 int *on = arg;
1906                 pr_debug("   VIDIOC_OVERLAY on=%d\n", *on);
1907                 if (*on) {
1908                         cam->overlay_on = true;
1909                         cam->overlay_pid = current->pid;
1910                         retval = start_preview(cam);
1911                 }
1912                 if (!*on) {
1913                         retval = stop_preview(cam);
1914                         cam->overlay_on = false;
1915                 }
1916                 break;
1917         }
1918
1919         /*!
1920          * V4l2 VIDIOC_G_FBUF ioctl
1921          */
1922         case VIDIOC_G_FBUF: {
1923                 struct v4l2_framebuffer *fb = arg;
1924                 pr_debug("   case VIDIOC_G_FBUF\n");
1925                 *fb = cam->v4l2_fb;
1926                 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY;
1927                 break;
1928         }
1929
1930         /*!
1931          * V4l2 VIDIOC_S_FBUF ioctl
1932          */
1933         case VIDIOC_S_FBUF: {
1934                 struct v4l2_framebuffer *fb = arg;
1935                 pr_debug("   case VIDIOC_S_FBUF\n");
1936                 cam->v4l2_fb = *fb;
1937                 break;
1938         }
1939
1940         case VIDIOC_G_PARM: {
1941                 struct v4l2_streamparm *parm = arg;
1942                 pr_debug("   case VIDIOC_G_PARM\n");
1943                 vidioc_int_g_parm(cam->sensor, parm);
1944                 break;
1945         }
1946
1947         case VIDIOC_S_PARM:  {
1948                 struct v4l2_streamparm *parm = arg;
1949                 pr_debug("   case VIDIOC_S_PARM\n");
1950                 retval = mxc_v4l2_s_param(cam, parm);
1951                 break;
1952         }
1953
1954         /* linux v4l2 bug, kernel c0485619 user c0405619 */
1955         case VIDIOC_ENUMSTD: {
1956                 struct v4l2_standard *e = arg;
1957                 pr_debug("   case VIDIOC_ENUMSTD\n");
1958                 *e = cam->standard;
1959                 break;
1960         }
1961
1962         case VIDIOC_G_STD: {
1963                 v4l2_std_id *e = arg;
1964                 pr_debug("   case VIDIOC_G_STD\n");
1965                 retval = mxc_v4l2_g_std(cam, e);
1966                 break;
1967         }
1968
1969         case VIDIOC_S_STD: {
1970                 v4l2_std_id *e = arg;
1971                 pr_debug("   case VIDIOC_S_STD\n");
1972                 retval = mxc_v4l2_s_std(cam, *e);
1973
1974                 break;
1975         }
1976
1977         case VIDIOC_ENUMOUTPUT: {
1978                 struct v4l2_output *output = arg;
1979                 pr_debug("   case VIDIOC_ENUMOUTPUT\n");
1980                 if (output->index >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) {
1981                         retval = -EINVAL;
1982                         break;
1983                 }
1984                 *output = mxc_capture_outputs[output->index];
1985
1986                 break;
1987         }
1988         case VIDIOC_G_OUTPUT: {
1989                 int *p_output_num = arg;
1990                 pr_debug("   case VIDIOC_G_OUTPUT\n");
1991                 *p_output_num = cam->output;
1992                 break;
1993         }
1994
1995         case VIDIOC_S_OUTPUT: {
1996                 int *p_output_num = arg;
1997                 pr_debug("   case VIDIOC_S_OUTPUT\n");
1998                 if (*p_output_num >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) {
1999                         retval = -EINVAL;
2000                         break;
2001                 }
2002                 cam->output = *p_output_num;
2003                 break;
2004         }
2005
2006         case VIDIOC_ENUMINPUT: {
2007                 struct v4l2_input *input = arg;
2008                 pr_debug("   case VIDIOC_ENUMINPUT\n");
2009                 if (input->index >= MXC_V4L2_CAPTURE_NUM_INPUTS) {
2010                         retval = -EINVAL;
2011                         break;
2012                 }
2013                 *input = mxc_capture_inputs[input->index];
2014                 break;
2015         }
2016
2017         case VIDIOC_G_INPUT: {
2018                 int *index = arg;
2019                 pr_debug("   case VIDIOC_G_INPUT\n");
2020                 *index = cam->current_input;
2021                 break;
2022         }
2023
2024         case VIDIOC_S_INPUT: {
2025                 int *index = arg;
2026                 pr_debug("   case VIDIOC_S_INPUT\n");
2027                 if (*index >= MXC_V4L2_CAPTURE_NUM_INPUTS) {
2028                         retval = -EINVAL;
2029                         break;
2030                 }
2031
2032                 if (*index == cam->current_input)
2033                         break;
2034
2035                 if ((mxc_capture_inputs[cam->current_input].status &
2036                     V4L2_IN_ST_NO_POWER) == 0) {
2037                         retval = mxc_streamoff(cam);
2038                         if (retval)
2039                                 break;
2040                         mxc_capture_inputs[cam->current_input].status |=
2041                                                         V4L2_IN_ST_NO_POWER;
2042                 }
2043
2044                 if (strcmp(mxc_capture_inputs[*index].name, "CSI MEM") == 0) {
2045 #if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
2046                         retval = csi_enc_select(cam);
2047                         if (retval)
2048                                 break;
2049 #endif
2050                 } else if (strcmp(mxc_capture_inputs[*index].name,
2051                                   "CSI IC MEM") == 0) {
2052 #if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
2053                         retval = prp_enc_select(cam);
2054                         if (retval)
2055                                 break;
2056 #endif
2057                 }
2058
2059                 mxc_capture_inputs[*index].status &= ~V4L2_IN_ST_NO_POWER;
2060                 cam->current_input = *index;
2061                 break;
2062         }
2063
2064         case VIDIOC_ENUM_FMT:
2065         case VIDIOC_TRY_FMT:
2066         case VIDIOC_QUERYCTRL:
2067         case VIDIOC_G_TUNER:
2068         case VIDIOC_S_TUNER:
2069         case VIDIOC_G_FREQUENCY:
2070         case VIDIOC_S_FREQUENCY:
2071         default:
2072                 pr_debug("   case default or not supported\n");
2073                 retval = -EINVAL;
2074                 break;
2075         }
2076
2077         up(&cam->busy_lock);
2078         return retval;
2079 }
2080
2081 /*
2082  * V4L interface - ioctl function
2083  *
2084  * @return  None
2085  */
2086 static int mxc_v4l_ioctl(struct inode *inode, struct file *file,
2087                          unsigned int cmd, unsigned long arg)
2088 {
2089         pr_debug("In MVC:mxc_v4l_ioctl\n");
2090         return video_usercopy(inode, file, cmd, arg, mxc_v4l_do_ioctl);
2091 }
2092
2093 /*!
2094  * V4L interface - mmap function
2095  *
2096  * @param file        structure file *
2097  *
2098  * @param vma         structure vm_area_struct *
2099  *
2100  * @return status     0 Success, EINTR busy lock error, ENOBUFS remap_page error
2101  */
2102 static int mxc_mmap(struct file *file, struct vm_area_struct *vma)
2103 {
2104         struct video_device *dev = video_devdata(file);
2105         unsigned long size;
2106         int res = 0;
2107         cam_data *cam = video_get_drvdata(dev);
2108
2109         pr_debug("In MVC:mxc_mmap\n");
2110         pr_debug("   pgoff=0x%lx, start=0x%lx, end=0x%lx\n",
2111                  vma->vm_pgoff, vma->vm_start, vma->vm_end);
2112
2113         /* make this _really_ smp-safe */
2114         if (down_interruptible(&cam->busy_lock))
2115                 return -EINTR;
2116
2117         size = vma->vm_end - vma->vm_start;
2118         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
2119
2120         if (remap_pfn_range(vma, vma->vm_start,
2121                             vma->vm_pgoff, size, vma->vm_page_prot)) {
2122                 pr_err("ERROR: v4l2 capture: mxc_mmap: "
2123                         "remap_pfn_range failed\n");
2124                 res = -ENOBUFS;
2125                 goto mxc_mmap_exit;
2126         }
2127
2128         vma->vm_flags &= ~VM_IO;        /* using shared anonymous pages */
2129
2130       mxc_mmap_exit:
2131         up(&cam->busy_lock);
2132         return res;
2133 }
2134
2135 /*!
2136  * V4L interface - poll function
2137  *
2138  * @param file       structure file *
2139  *
2140  * @param wait       structure poll_table *
2141  *
2142  * @return  status   POLLIN | POLLRDNORM
2143  */
2144 static unsigned int mxc_poll(struct file *file, poll_table *wait)
2145 {
2146         struct video_device *dev = video_devdata(file);
2147         cam_data *cam = video_get_drvdata(dev);
2148         wait_queue_head_t *queue = NULL;
2149         int res = POLLIN | POLLRDNORM;
2150
2151         pr_debug("In MVC:mxc_poll\n");
2152
2153         if (down_interruptible(&cam->busy_lock))
2154                 return -EINTR;
2155
2156         queue = &cam->enc_queue;
2157         poll_wait(file, queue, wait);
2158
2159         up(&cam->busy_lock);
2160
2161         return res;
2162 }
2163
2164 /*!
2165  * This structure defines the functions to be called in this driver.
2166  */
2167 static struct file_operations mxc_v4l_fops = {
2168         .owner = THIS_MODULE,
2169         .open = mxc_v4l_open,
2170         .release = mxc_v4l_close,
2171         .read = mxc_v4l_read,
2172         .ioctl = mxc_v4l_ioctl,
2173         .mmap = mxc_mmap,
2174         .poll = mxc_poll,
2175 };
2176
2177 static struct video_device mxc_v4l_template = {
2178         .name = "Mxc Camera",
2179         .vfl_type = VID_TYPE_CAPTURE,
2180         .fops = &mxc_v4l_fops,
2181         .release = video_device_release,
2182 };
2183
2184 /*!
2185  * This function can be used to release any platform data on closing.
2186  */
2187 static void camera_platform_release(struct device *device)
2188 {
2189 }
2190
2191 /*! Device Definition for Mt9v111 devices */
2192 static struct platform_device mxc_v4l2_devices = {
2193         .name = "mxc_v4l2",
2194         .dev = {
2195                 .release = camera_platform_release,
2196                 },
2197         .id = 0,
2198 };
2199
2200 /*!
2201  * Camera V4l2 callback function.
2202  *
2203  * @param mask      u32
2204  *
2205  * @param dev       void device structure
2206  *
2207  * @return status
2208  */
2209 static void camera_callback(u32 mask, void *dev)
2210 {
2211         struct mxc_v4l_frame *done_frame;
2212         struct mxc_v4l_frame *ready_frame;
2213
2214         cam_data *cam = (cam_data *) dev;
2215         if (cam == NULL)
2216                 return;
2217
2218         pr_debug("In MVC:camera_callback\n");
2219
2220         if (list_empty(&cam->working_q)) {
2221                 pr_err("ERROR: v4l2 capture: camera_callback: "
2222                         "working queue empty\n");
2223                 return;
2224         }
2225
2226         done_frame =
2227                 list_entry(cam->working_q.next, struct mxc_v4l_frame, queue);
2228         if (done_frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
2229                 done_frame->buffer.flags |= V4L2_BUF_FLAG_DONE;
2230                 done_frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
2231
2232                 if (list_empty(&cam->ready_q)) {
2233                         cam->skip_frame++;
2234                 } else {
2235                         ready_frame = list_entry(cam->ready_q.next,
2236                                                  struct mxc_v4l_frame,
2237                                                  queue);
2238                         list_del(cam->ready_q.next);
2239                         list_add_tail(&ready_frame->queue, &cam->working_q);
2240                         cam->enc_update_eba(ready_frame->buffer.m.offset,
2241                                             &cam->ping_pong_csi);
2242                 }
2243
2244                 /* Added to the done queue */
2245                 list_del(cam->working_q.next);
2246                 list_add_tail(&done_frame->queue, &cam->done_q);
2247
2248                 /* Wake up the queue */
2249                 cam->enc_counter++;
2250                 wake_up_interruptible(&cam->enc_queue);
2251         } else {
2252                 pr_err("ERROR: v4l2 capture: camera_callback: "
2253                         "buffer not queued\n");
2254         }
2255 }
2256
2257 /*!
2258  * initialize cam_data structure
2259  *
2260  * @param cam      structure cam_data *
2261  *
2262  * @return status  0 Success
2263  */
2264 static void init_camera_struct(cam_data *cam)
2265 {
2266         pr_debug("In MVC: init_camera_struct\n");
2267
2268         /* Default everything to 0 */
2269         memset(cam, 0, sizeof(cam_data));
2270
2271         init_MUTEX(&cam->param_lock);
2272         init_MUTEX(&cam->busy_lock);
2273
2274         cam->video_dev = video_device_alloc();
2275         if (cam->video_dev == NULL)
2276                 return;
2277
2278         *(cam->video_dev) = mxc_v4l_template;
2279
2280         video_set_drvdata(cam->video_dev, cam);
2281         dev_set_drvdata(&mxc_v4l2_devices.dev, (void *)cam);
2282         cam->video_dev->minor = -1;
2283
2284         init_waitqueue_head(&cam->enc_queue);
2285         init_waitqueue_head(&cam->still_queue);
2286
2287         /* setup cropping */
2288         cam->crop_bounds.left = 0;
2289         cam->crop_bounds.width = 640;
2290         cam->crop_bounds.top = 0;
2291         cam->crop_bounds.height = 480;
2292         cam->crop_current = cam->crop_defrect = cam->crop_bounds;
2293         ipu_csi_set_window_size(cam->crop_current.width,
2294                                 cam->crop_current.height, cam->csi);
2295         ipu_csi_set_window_pos(cam->crop_current.left,
2296                                 cam->crop_current.top, cam->csi);
2297         cam->streamparm.parm.capture.capturemode = 0;
2298
2299         cam->standard.index = 0;
2300         cam->standard.id = V4L2_STD_UNKNOWN;
2301         cam->standard.frameperiod.denominator = 30;
2302         cam->standard.frameperiod.numerator = 1;
2303         cam->standard.framelines = 480;
2304         cam->standard_autodetect = true;
2305         cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2306         cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod;
2307         cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
2308         cam->overlay_on = false;
2309         cam->capture_on = false;
2310         cam->skip_frame = 0;
2311         cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY;
2312
2313         cam->v2f.fmt.pix.sizeimage = 352 * 288 * 3 / 2;
2314         cam->v2f.fmt.pix.bytesperline = 288 * 3 / 2;
2315         cam->v2f.fmt.pix.width = 288;
2316         cam->v2f.fmt.pix.height = 352;
2317         cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
2318         cam->win.w.width = 160;
2319         cam->win.w.height = 160;
2320         cam->win.w.left = 0;
2321         cam->win.w.top = 0;
2322
2323         cam->csi = 0;  /* Need to determine how to set this correctly with
2324                         * multiple video input devices. */
2325
2326         cam->enc_callback = camera_callback;
2327         init_waitqueue_head(&cam->power_queue);
2328         spin_lock_init(&cam->int_lock);
2329 }
2330
2331 /*!
2332  * camera_power function
2333  *    Turns Sensor power On/Off
2334  *
2335  * @param       cam           cam data struct
2336  * @param       cameraOn      true to turn camera on, false to turn off power.
2337  *
2338  * @return status
2339  */
2340 static u8 camera_power(cam_data *cam, bool cameraOn)
2341 {
2342         pr_debug("In MVC:camera_power on=%d\n", cameraOn);
2343
2344         if (cameraOn == true) {
2345                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true);
2346                 vidioc_int_s_power(cam->sensor, 1);
2347         } else {
2348                 ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false);
2349                 vidioc_int_s_power(cam->sensor, 0);
2350         }
2351         return 0;
2352 }
2353
2354 /*!
2355  * This function is called to put the sensor in a low power state.
2356  * Refer to the document driver-model/driver.txt in the kernel source tree
2357  * for more information.
2358  *
2359  * @param   pdev  the device structure used to give information on which I2C
2360  *                to suspend
2361  * @param   state the power state the device is entering
2362  *
2363  * @return  The function returns 0 on success and -1 on failure.
2364  */
2365 static int mxc_v4l2_suspend(struct platform_device *pdev, pm_message_t state)
2366 {
2367         cam_data *cam = platform_get_drvdata(pdev);
2368
2369         pr_debug("In MVC:mxc_v4l2_suspend\n");
2370
2371         if (cam == NULL) {
2372                 return -1;
2373         }
2374
2375         cam->low_power = true;
2376
2377         if (cam->overlay_on == true)
2378                 stop_preview(cam);
2379         if ((cam->capture_on == true) && cam->enc_disable) {
2380                 cam->enc_disable(cam);
2381         }
2382         camera_power(cam, false);
2383
2384         return 0;
2385 }
2386
2387 /*!
2388  * This function is called to bring the sensor back from a low power state.
2389  * Refer to the document driver-model/driver.txt in the kernel source tree
2390  * for more information.
2391  *
2392  * @param   pdev   the device structure
2393  *
2394  * @return  The function returns 0 on success and -1 on failure
2395  */
2396 static int mxc_v4l2_resume(struct platform_device *pdev)
2397 {
2398         cam_data *cam = platform_get_drvdata(pdev);
2399
2400         pr_debug("In MVC:mxc_v4l2_resume\n");
2401
2402         if (cam == NULL) {
2403                 return -1;
2404         }
2405
2406         cam->low_power = false;
2407         wake_up_interruptible(&cam->power_queue);
2408         camera_power(cam, true);
2409
2410         if (cam->overlay_on == true)
2411                 start_preview(cam);
2412         if (cam->capture_on == true)
2413                 mxc_streamon(cam);
2414
2415         return 0;
2416 }
2417
2418 /*!
2419  * This structure contains pointers to the power management callback functions.
2420  */
2421 static struct platform_driver mxc_v4l2_driver = {
2422         .driver = {
2423                    .name = "mxc_v4l2",
2424                    },
2425         .probe = NULL,
2426         .remove = NULL,
2427         .suspend = mxc_v4l2_suspend,
2428         .resume = mxc_v4l2_resume,
2429         .shutdown = NULL,
2430 };
2431
2432 /*!
2433  * Initializes the camera driver.
2434  */
2435 static int mxc_v4l2_master_attach(struct v4l2_int_device *slave)
2436 {
2437         cam_data *cam = slave->u.slave->master->priv;
2438         struct v4l2_format cam_fmt;
2439
2440         pr_debug("In MVC: mxc_v4l2_master_attach\n");
2441         pr_debug("   slave.name = %s\n", slave->name);
2442         pr_debug("   master.name = %s\n", slave->u.slave->master->name);
2443
2444         cam->sensor = slave;
2445         if (slave == NULL) {
2446                 pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
2447                 return -1;
2448         }
2449
2450         ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, true, true);
2451         vidioc_int_dev_init(slave);
2452         ipu_csi_enable_mclk_if(CSI_MCLK_I2C, cam->csi, false, false);
2453         cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2454         vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
2455
2456         /* Used to detect TV in (type 1) vs. camera (type 0)*/
2457         cam->device_type = cam_fmt.fmt.pix.priv;
2458
2459         /* Set the input size to the ipu for this device */
2460         cam->crop_bounds.top = cam->crop_bounds.left = 0;
2461         cam->crop_bounds.width = cam_fmt.fmt.pix.width;
2462         cam->crop_bounds.height = cam_fmt.fmt.pix.height;
2463
2464         /* This also is the max crop size for this device. */
2465         cam->crop_defrect.top = cam->crop_defrect.left = 0;
2466         cam->crop_defrect.width = cam_fmt.fmt.pix.width;
2467         cam->crop_defrect.height = cam_fmt.fmt.pix.height;
2468
2469         /* At this point, this is also the current image size. */
2470         cam->crop_current.top = cam->crop_current.left = 0;
2471         cam->crop_current.width = cam_fmt.fmt.pix.width;
2472         cam->crop_current.height = cam_fmt.fmt.pix.height;
2473
2474         pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
2475                  __func__,
2476                  cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
2477         pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
2478                  __func__,
2479                  cam->crop_bounds.width, cam->crop_bounds.height);
2480         pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
2481                  __func__,
2482                  cam->crop_defrect.width, cam->crop_defrect.height);
2483         pr_debug("End of %s: crop_current widthxheight %d x %d\n",
2484                  __func__,
2485                  cam->crop_current.width, cam->crop_current.height);
2486
2487         return 0;
2488 }
2489
2490 /*!