2 * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved.
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:
10 * http://www.opensource.org/licenses/gpl-license.html
11 * http://www.gnu.org/copyleft/gpl.html
15 * @file drivers/media/video/mxc/capture/mxc_v4l2_capture.c
17 * @brief Mxc Video For Linux 2 driver
19 * @ingroup MXC_V4L2_CAPTURE
21 #include <linux/version.h>
22 #include <linux/module.h>
23 #include <linux/init.h>
24 #include <linux/platform_device.h>
26 #include <linux/slab.h>
27 #include <linux/ctype.h>
28 #include <linux/clk.h>
30 #include <linux/semaphore.h>
31 #include <linux/pagemap.h>
32 #include <linux/vmalloc.h>
33 #include <linux/types.h>
35 #include <linux/dma-mapping.h>
36 #include <linux/delay.h>
37 #include <linux/mxcfb.h>
38 #include <linux/of_device.h>
39 #include <media/v4l2-chip-ident.h>
40 #include <media/v4l2-ioctl.h>
41 #include <media/v4l2-int-device.h>
42 #include <linux/fsl_devices.h>
43 #include "mxc_v4l2_capture.h"
44 #include "ipu_prp_sw.h"
46 #define init_MUTEX(sem) sema_init(sem, 1)
47 #define MXC_SENSOR_NUM 2
49 static struct platform_device_id imx_v4l2_devtype[] = {
51 .name = "v4l2-capture-imx5",
52 .driver_data = IMX5_V4L2,
54 .name = "v4l2-capture-imx6",
55 .driver_data = IMX6_V4L2,
60 MODULE_DEVICE_TABLE(platform, imx_v4l2_devtype);
62 static const struct of_device_id mxc_v4l2_dt_ids[] = {
64 .compatible = "fsl,imx6q-v4l2-capture",
65 .data = &imx_v4l2_devtype[IMX6_V4L2],
70 MODULE_DEVICE_TABLE(of, mxc_v4l2_dt_ids);
72 static int video_nr = -1;
74 /*! This data is used for the output to the display. */
75 #define MXC_V4L2_CAPTURE_NUM_OUTPUTS 6
76 #define MXC_V4L2_CAPTURE_NUM_INPUTS 2
77 static struct v4l2_output mxc_capture_outputs[MXC_V4L2_CAPTURE_NUM_OUTPUTS] = {
81 .type = V4L2_OUTPUT_TYPE_ANALOG,
84 .std = V4L2_STD_UNKNOWN,
88 .name = "DISP3 BG - DI1",
89 .type = V4L2_OUTPUT_TYPE_ANALOG,
92 .std = V4L2_STD_UNKNOWN,
97 .type = V4L2_OUTPUT_TYPE_ANALOG,
100 .std = V4L2_STD_UNKNOWN,
105 .type = V4L2_OUTPUT_TYPE_ANALOG,
108 .std = V4L2_STD_UNKNOWN,
112 .name = "DISP4 BG - DI1",
113 .type = V4L2_OUTPUT_TYPE_ANALOG,
116 .std = V4L2_STD_UNKNOWN,
121 .type = V4L2_OUTPUT_TYPE_ANALOG,
124 .std = V4L2_STD_UNKNOWN,
128 static struct v4l2_input mxc_capture_inputs[MXC_V4L2_CAPTURE_NUM_INPUTS] = {
131 .name = "CSI IC MEM",
132 .type = V4L2_INPUT_TYPE_CAMERA,
135 .std = V4L2_STD_UNKNOWN,
141 .type = V4L2_INPUT_TYPE_CAMERA,
144 .std = V4L2_STD_UNKNOWN,
145 .status = V4L2_IN_ST_NO_POWER,
149 /*! List of TV input video formats supported. The video formats is corresponding
150 * to the v4l2_id in video_fmt_t.
151 * Currently, only PAL and NTSC is supported. Needs to be expanded in the
155 TV_NTSC = 0, /*!< Locked on (M) NTSC video signal. */
156 TV_PAL, /*!< (B, G, H, I, N)PAL video signal. */
157 TV_NOT_LOCKED, /*!< Not locked on a signal. */
160 /*! Number of video standards supported (including 'not locked' signal). */
161 #define TV_STD_MAX (TV_NOT_LOCKED + 1)
163 /*! Video format structure. */
165 int v4l2_id; /*!< Video for linux ID. */
166 char name[16]; /*!< Name (e.g., "NTSC", "PAL", etc.) */
167 u16 raw_width; /*!< Raw width. */
168 u16 raw_height; /*!< Raw height. */
169 u16 active_width; /*!< Active width. */
170 u16 active_height; /*!< Active height. */
171 u16 active_top; /*!< Active top. */
172 u16 active_left; /*!< Active left. */
176 * Description of video formats supported.
178 * PAL: raw=720x625, active=720x576.
179 * NTSC: raw=720x525, active=720x480.
181 static video_fmt_t video_fmts[] = {
183 .v4l2_id = V4L2_STD_NTSC,
185 .raw_width = 720, /* SENS_FRM_WIDTH */
186 .raw_height = 525, /* SENS_FRM_HEIGHT */
187 .active_width = 720, /* ACT_FRM_WIDTH */
188 .active_height = 480, /* ACT_FRM_HEIGHT */
192 { /*! (B, G, H, I, N) PAL */
193 .v4l2_id = V4L2_STD_PAL,
198 .active_height = 576,
202 { /*! Unlocked standard */
203 .v4l2_id = V4L2_STD_ALL,
204 .name = "Autodetect",
208 .active_height = 576,
214 /*!* Standard index of TV. */
215 static video_fmt_idx video_index = TV_NOT_LOCKED;
217 static int mxc_v4l2_master_attach(struct v4l2_int_device *slave);
218 static void mxc_v4l2_master_detach(struct v4l2_int_device *slave);
219 static int start_preview(cam_data *cam);
220 static int stop_preview(cam_data *cam);
222 /*! Information about this driver. */
223 static struct v4l2_int_master mxc_v4l2_master = {
224 .attach = mxc_v4l2_master_attach,
225 .detach = mxc_v4l2_master_detach,
228 /***************************************************************************
229 * Functions for handling Frame buffers.
230 **************************************************************************/
235 * @param cam Structure cam_data *
237 * @return status 0 success.
239 static int mxc_free_frame_buf(cam_data *cam)
243 pr_debug("MVC: In mxc_free_frame_buf\n");
245 for (i = 0; i < FRAME_NUM; i++) {
246 if (cam->frame[i].vaddress != 0) {
247 dma_free_coherent(0, cam->frame[i].buffer.length,
248 cam->frame[i].vaddress,
249 cam->frame[i].paddress);
250 cam->frame[i].vaddress = 0;
258 * Allocate frame buffers
260 * @param cam Structure cam_data*
261 * @param count int number of buffer need to allocated
263 * @return status -0 Successfully allocated a buffer, -ENOBUFS failed.
265 static int mxc_allocate_frame_buf(cam_data *cam, int count)
269 pr_debug("In MVC:mxc_allocate_frame_buf - size=%d\n",
270 cam->v2f.fmt.pix.sizeimage);
272 for (i = 0; i < count; i++) {
273 cam->frame[i].vaddress =
274 dma_alloc_coherent(0,
275 PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
276 &cam->frame[i].paddress,
277 GFP_DMA | GFP_KERNEL);
278 if (cam->frame[i].vaddress == 0) {
279 pr_err("ERROR: v4l2 capture: "
280 "mxc_allocate_frame_buf failed.\n");
281 mxc_free_frame_buf(cam);
284 cam->frame[i].buffer.index = i;
285 cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
286 cam->frame[i].buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
287 cam->frame[i].buffer.length =
288 PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage);
289 cam->frame[i].buffer.memory = V4L2_MEMORY_MMAP;
290 cam->frame[i].buffer.m.offset = cam->frame[i].paddress;
291 cam->frame[i].index = i;
298 * Free frame buffers status
300 * @param cam Structure cam_data *
304 static void mxc_free_frames(cam_data *cam)
308 pr_debug("In MVC:mxc_free_frames\n");
310 for (i = 0; i < FRAME_NUM; i++)
311 cam->frame[i].buffer.flags = V4L2_BUF_FLAG_MAPPED;
313 cam->enc_counter = 0;
314 INIT_LIST_HEAD(&cam->ready_q);
315 INIT_LIST_HEAD(&cam->working_q);
316 INIT_LIST_HEAD(&cam->done_q);
320 * Return the buffer status
322 * @param cam Structure cam_data *
323 * @param buf Structure v4l2_buffer *
325 * @return status 0 success, EINVAL failed.
327 static int mxc_v4l2_buffer_status(cam_data *cam, struct v4l2_buffer *buf)
329 pr_debug("In MVC:mxc_v4l2_buffer_status\n");
331 if (buf->index < 0 || buf->index >= FRAME_NUM) {
332 pr_err("ERROR: v4l2 capture: mxc_v4l2_buffer_status buffers "
337 memcpy(buf, &(cam->frame[buf->index].buffer), sizeof(*buf));
341 static int mxc_v4l2_release_bufs(cam_data *cam)
343 pr_debug("In MVC:mxc_v4l2_release_bufs\n");
347 static int mxc_v4l2_prepare_bufs(cam_data *cam, struct v4l2_buffer *buf)
349 pr_debug("In MVC:mxc_v4l2_prepare_bufs\n");
351 if (buf->index < 0 || buf->index >= FRAME_NUM || buf->length <
352 PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage)) {
353 pr_err("ERROR: v4l2 capture: mxc_v4l2_prepare_bufs buffers "
354 "not allocated,index=%d, length=%d\n", buf->index,
359 cam->frame[buf->index].buffer.index = buf->index;
360 cam->frame[buf->index].buffer.flags = V4L2_BUF_FLAG_MAPPED;
361 cam->frame[buf->index].buffer.length = buf->length;
362 cam->frame[buf->index].buffer.m.offset = cam->frame[buf->index].paddress
364 cam->frame[buf->index].buffer.type = buf->type;
365 cam->frame[buf->index].buffer.memory = V4L2_MEMORY_USERPTR;
366 cam->frame[buf->index].index = buf->index;
371 /***************************************************************************
372 * Functions for handling the video stream.
373 **************************************************************************/
376 * Indicates whether the palette is supported.
378 * @param palette V4L2_PIX_FMT_RGB565, V4L2_PIX_FMT_BGR24 or V4L2_PIX_FMT_BGR32
380 * @return 0 if failed
382 static inline int valid_mode(u32 palette)
384 return ((palette == V4L2_PIX_FMT_RGB565) ||
385 (palette == V4L2_PIX_FMT_BGR24) ||
386 (palette == V4L2_PIX_FMT_RGB24) ||
387 (palette == V4L2_PIX_FMT_BGR32) ||
388 (palette == V4L2_PIX_FMT_RGB32) ||
389 (palette == V4L2_PIX_FMT_YUV422P) ||
390 (palette == V4L2_PIX_FMT_UYVY) ||
391 (palette == V4L2_PIX_FMT_YUYV) ||
392 (palette == V4L2_PIX_FMT_YUV420) ||
393 (palette == V4L2_PIX_FMT_YVU420) ||
394 (palette == V4L2_PIX_FMT_NV12));
398 * Start the encoder job
400 * @param cam structure cam_data *
402 * @return status 0 Success
404 static int mxc_streamon(cam_data *cam)
406 struct mxc_v4l_frame *frame;
407 unsigned long lock_flags;
410 pr_debug("In MVC:mxc_streamon\n");
413 pr_err("ERROR! cam parameter is NULL\n");
417 if (cam->capture_on) {
418 pr_err("ERROR: v4l2 capture: Capture stream has been turned "
423 if (list_empty(&cam->ready_q)) {
424 pr_err("ERROR: v4l2 capture: mxc_streamon buffer has not been "
428 if (cam->enc_update_eba &&
429 cam->ready_q.prev == cam->ready_q.next) {
430 pr_err("ERROR: v4l2 capture: mxc_streamon buffer need "
431 "ping pong at least two buffers\n");
435 cam->capture_pid = current->pid;
437 if (cam->overlay_on == true)
440 if (cam->enc_enable) {
441 err = cam->enc_enable(cam);
446 spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
447 cam->ping_pong_csi = 0;
448 cam->local_buf_num = 0;
449 if (cam->enc_update_eba) {
451 list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
452 list_del(cam->ready_q.next);
453 list_add_tail(&frame->queue, &cam->working_q);
454 frame->ipu_buf_num = cam->ping_pong_csi;
455 err = cam->enc_update_eba(cam->ipu, frame->buffer.m.offset,
456 &cam->ping_pong_csi);
459 list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
460 list_del(cam->ready_q.next);
461 list_add_tail(&frame->queue, &cam->working_q);
462 frame->ipu_buf_num = cam->ping_pong_csi;
463 err |= cam->enc_update_eba(cam->ipu, frame->buffer.m.offset,
464 &cam->ping_pong_csi);
465 spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
467 spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
471 if (cam->overlay_on == true)
474 if (cam->enc_enable_csi) {
475 err = cam->enc_enable_csi(cam);
480 cam->capture_on = true;
486 * Shut down the encoder job
488 * @param cam structure cam_data *
490 * @return status 0 Success
492 static int mxc_streamoff(cam_data *cam)
496 pr_debug("In MVC:mxc_streamoff\n");
498 if (cam->capture_on == false)
501 /* For both CSI--MEM and CSI--IC--MEM
502 * 1. wait for idmac eof
503 * 2. disable csi first
505 * 4. disable smfc (CSI--MEM channel)
507 if (mxc_capture_inputs[cam->current_input].name != NULL) {
508 if (cam->enc_disable_csi) {
509 err = cam->enc_disable_csi(cam);
513 if (cam->enc_disable) {
514 err = cam->enc_disable(cam);
520 mxc_free_frames(cam);
521 mxc_capture_inputs[cam->current_input].status |= V4L2_IN_ST_NO_POWER;
522 cam->capture_on = false;
527 * Valid and adjust the overlay window size, position
529 * @param cam structure cam_data *
530 * @param win struct v4l2_window *
534 static int verify_preview(cam_data *cam, struct v4l2_window *win)
536 int i = 0, width_bound = 0, height_bound = 0;
538 unsigned int ipu_ch = CHAN_NONE;
539 struct fb_info *bg_fbi = NULL, *fbi = NULL;
540 bool foregound_fb = false;
543 pr_debug("In MVC: verify_preview\n");
546 fbi = (struct fb_info *)registered_fb[i];
548 pr_err("ERROR: verify_preview frame buffer NULL.\n");
552 /* Which DI supports 2 layers? */
553 if (((strncmp(fbi->fix.id, "DISP3 BG", 8) == 0) &&
554 (cam->output < 3)) ||
555 ((strncmp(fbi->fix.id, "DISP4 BG", 8) == 0) &&
556 (cam->output >= 3))) {
557 if (fbi->fbops->fb_ioctl) {
560 fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_IPU_CHAN,
561 (unsigned long)&ipu_ch);
564 if (ipu_ch == MEM_BG_SYNC) {
566 pr_debug("Found background frame buffer.\n");
570 /* Found the frame buffer to preview on. */
571 if (strcmp(fbi->fix.id,
572 mxc_capture_outputs[cam->output].name) == 0) {
573 if (((strcmp(fbi->fix.id, "DISP3 FG") == 0) &&
574 (cam->output < 3)) ||
575 ((strcmp(fbi->fix.id, "DISP4 FG") == 0) &&
579 cam->overlay_fb = fbi;
582 } while (++i < FB_MAX);
585 width_bound = bg_fbi->var.xres;
586 height_bound = bg_fbi->var.yres;
588 if (win->w.width + win->w.left > bg_fbi->var.xres ||
589 win->w.height + win->w.top > bg_fbi->var.yres) {
590 pr_err("ERROR: FG window position exceeds.\n");
594 /* 4 bytes alignment for BG */
595 width_bound = cam->overlay_fb->var.xres;
596 height_bound = cam->overlay_fb->var.yres;
598 if (cam->overlay_fb->var.bits_per_pixel == 24)
599 win->w.left -= win->w.left % 4;
600 else if (cam->overlay_fb->var.bits_per_pixel == 16)
601 win->w.left -= win->w.left % 2;
603 if (win->w.width + win->w.left > cam->overlay_fb->var.xres)
604 win->w.width = cam->overlay_fb->var.xres - win->w.left;
605 if (win->w.height + win->w.top > cam->overlay_fb->var.yres)
606 win->w.height = cam->overlay_fb->var.yres - win->w.top;
609 /* stride line limitation */
610 win->w.height -= win->w.height % 8;
611 win->w.width -= win->w.width % 8;
613 if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
614 height = &win->w.width;
615 width = &win->w.height;
617 width = &win->w.width;
618 height = &win->w.height;
621 if (*width == 0 || *height == 0) {
622 pr_err("ERROR: v4l2 capture: width or height"
627 if ((cam->crop_bounds.width / *width > 8) ||
628 ((cam->crop_bounds.width / *width == 8) &&
629 (cam->crop_bounds.width % *width))) {
630 *width = cam->crop_bounds.width / 8;
632 *width += 8 - *width % 8;
633 if (*width + win->w.left > width_bound) {
634 pr_err("ERROR: v4l2 capture: width exceeds "
638 pr_err("ERROR: v4l2 capture: width exceeds limit. "
643 if ((cam->crop_bounds.height / *height > 8) ||
644 ((cam->crop_bounds.height / *height == 8) &&
645 (cam->crop_bounds.height % *height))) {
646 *height = cam->crop_bounds.height / 8;
648 *height += 8 - *height % 8;
649 if (*height + win->w.top > height_bound) {
650 pr_err("ERROR: v4l2 capture: height exceeds "
654 pr_err("ERROR: v4l2 capture: height exceeds limit "
663 * start the viewfinder job
665 * @param cam structure cam_data *
667 * @return status 0 Success
669 static int start_preview(cam_data *cam)
673 pr_debug("MVC: start_preview\n");
675 if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
676 #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
677 err = prp_vf_sdc_select(cam);
679 err = foreground_sdc_select(cam);
681 else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
682 #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
683 err = prp_vf_sdc_select_bg(cam);
685 err = bg_overlay_sdc_select(cam);
690 if (cam->vf_start_sdc) {
691 err = cam->vf_start_sdc(cam);
696 if (cam->vf_enable_csi)
697 err = cam->vf_enable_csi(cam);
699 pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
701 cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
702 pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
704 cam->crop_bounds.width, cam->crop_bounds.height);
705 pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
707 cam->crop_defrect.width, cam->crop_defrect.height);
708 pr_debug("End of %s: crop_current widthxheight %d x %d\n",
710 cam->crop_current.width, cam->crop_current.height);
716 * shut down the viewfinder job
718 * @param cam structure cam_data *
720 * @return status 0 Success
722 static int stop_preview(cam_data *cam)
726 if (cam->vf_disable_csi) {
727 err = cam->vf_disable_csi(cam);
732 if (cam->vf_stop_sdc) {
733 err = cam->vf_stop_sdc(cam);
738 if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
739 #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
740 err = prp_vf_sdc_deselect(cam);
742 err = foreground_sdc_deselect(cam);
744 else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
745 #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
746 err = prp_vf_sdc_deselect_bg(cam);
748 err = bg_overlay_sdc_deselect(cam);
754 /***************************************************************************
756 **************************************************************************/
759 * V4L2 - mxc_v4l2_g_fmt function
761 * @param cam structure cam_data *
763 * @param f structure v4l2_format *
765 * @return status 0 success, EINVAL failed
767 static int mxc_v4l2_g_fmt(cam_data *cam, struct v4l2_format *f)
771 pr_debug("In MVC: mxc_v4l2_g_fmt type=%d\n", f->type);
774 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
775 pr_debug(" type is V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
776 f->fmt.pix = cam->v2f.fmt.pix;
778 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
779 pr_debug(" type is V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
780 f->fmt.win = cam->win;
783 pr_debug(" type is invalid\n");
787 pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
789 cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
790 pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
792 cam->crop_bounds.width, cam->crop_bounds.height);
793 pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
795 cam->crop_defrect.width, cam->crop_defrect.height);
796 pr_debug("End of %s: crop_current widthxheight %d x %d\n",
798 cam->crop_current.width, cam->crop_current.height);
804 * V4L2 - mxc_v4l2_s_fmt function
806 * @param cam structure cam_data *
808 * @param f structure v4l2_format *
810 * @return status 0 success, EINVAL failed
812 static int mxc_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
816 int bytesperline = 0;
819 pr_debug("In MVC: mxc_v4l2_s_fmt\n");
822 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
823 pr_debug(" type=V4L2_BUF_TYPE_VIDEO_CAPTURE\n");
824 if (!valid_mode(f->fmt.pix.pixelformat)) {
825 pr_err("ERROR: v4l2 capture: mxc_v4l2_s_fmt: format "
831 * Force the capture window resolution to be crop bounds
832 * for CSI MEM input mode.
834 if (strcmp(mxc_capture_inputs[cam->current_input].name,
836 f->fmt.pix.width = cam->crop_current.width;
837 f->fmt.pix.height = cam->crop_current.height;
840 if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
841 height = &f->fmt.pix.width;
842 width = &f->fmt.pix.height;
844 width = &f->fmt.pix.width;
845 height = &f->fmt.pix.height;
848 /* stride line limitation */
849 *width -= *width % 8;
850 *height -= *height % 8;
852 if (*width == 0 || *height == 0) {
853 pr_err("ERROR: v4l2 capture: width or height"
858 if ((cam->crop_current.width / *width > 8) ||
859 ((cam->crop_current.width / *width == 8) &&
860 (cam->crop_current.width % *width))) {
861 *width = cam->crop_current.width / 8;
863 *width += 8 - *width % 8;
864 pr_err("ERROR: v4l2 capture: width exceeds limit "
869 if ((cam->crop_current.height / *height > 8) ||
870 ((cam->crop_current.height / *height == 8) &&
871 (cam->crop_current.height % *height))) {
872 *height = cam->crop_current.height / 8;
874 *height += 8 - *height % 8;
875 pr_err("ERROR: v4l2 capture: height exceeds limit "
880 switch (f->fmt.pix.pixelformat) {
881 case V4L2_PIX_FMT_RGB565:
882 size = f->fmt.pix.width * f->fmt.pix.height * 2;
883 bytesperline = f->fmt.pix.width * 2;
885 case V4L2_PIX_FMT_BGR24:
886 size = f->fmt.pix.width * f->fmt.pix.height * 3;
887 bytesperline = f->fmt.pix.width * 3;
889 case V4L2_PIX_FMT_RGB24:
890 size = f->fmt.pix.width * f->fmt.pix.height * 3;
891 bytesperline = f->fmt.pix.width * 3;
893 case V4L2_PIX_FMT_BGR32:
894 size = f->fmt.pix.width * f->fmt.pix.height * 4;
895 bytesperline = f->fmt.pix.width * 4;
897 case V4L2_PIX_FMT_RGB32:
898 size = f->fmt.pix.width * f->fmt.pix.height * 4;
899 bytesperline = f->fmt.pix.width * 4;
901 case V4L2_PIX_FMT_YUV422P:
902 size = f->fmt.pix.width * f->fmt.pix.height * 2;
903 bytesperline = f->fmt.pix.width;
905 case V4L2_PIX_FMT_UYVY:
906 case V4L2_PIX_FMT_YUYV:
907 size = f->fmt.pix.width * f->fmt.pix.height * 2;
908 bytesperline = f->fmt.pix.width * 2;
910 case V4L2_PIX_FMT_YUV420:
911 case V4L2_PIX_FMT_YVU420:
912 size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
913 bytesperline = f->fmt.pix.width;
915 case V4L2_PIX_FMT_NV12:
916 size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
917 bytesperline = f->fmt.pix.width;
923 if (f->fmt.pix.bytesperline < bytesperline)
924 f->fmt.pix.bytesperline = bytesperline;
926 bytesperline = f->fmt.pix.bytesperline;
928 if (f->fmt.pix.sizeimage < size)
929 f->fmt.pix.sizeimage = size;
931 size = f->fmt.pix.sizeimage;
933 cam->v2f.fmt.pix = f->fmt.pix;
935 if (cam->v2f.fmt.pix.priv != 0) {
936 if (copy_from_user(&cam->offset,
937 (void *)cam->v2f.fmt.pix.priv,
938 sizeof(cam->offset))) {
944 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
945 pr_debug(" type=V4L2_BUF_TYPE_VIDEO_OVERLAY\n");
946 retval = verify_preview(cam, &f->fmt.win);
947 cam->win = f->fmt.win;
953 pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
955 cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
956 pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
958 cam->crop_bounds.width, cam->crop_bounds.height);
959 pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
961 cam->crop_defrect.width, cam->crop_defrect.height);
962 pr_debug("End of %s: crop_current widthxheight %d x %d\n",
964 cam->crop_current.width, cam->crop_current.height);
972 * @param cam structure cam_data *
974 * @param c structure v4l2_control *
976 * @return status 0 success, EINVAL failed
978 static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
982 pr_debug("In MVC:mxc_v4l2_g_ctrl\n");
984 /* probably don't need to store the values that can be retrieved,
985 * locally, but they are for now. */
988 /* This is handled in the ipu. */
989 if (cam->rotation == IPU_ROTATE_HORIZ_FLIP)
993 /* This is handled in the ipu. */
994 if (cam->rotation == IPU_ROTATE_VERT_FLIP)
997 case V4L2_CID_MXC_ROT:
998 /* This is handled in the ipu. */
999 c->value = cam->rotation;
1001 case V4L2_CID_BRIGHTNESS:
1003 c->value = cam->bright;
1004 status = vidioc_int_g_ctrl(cam->sensor, c);
1005 cam->bright = c->value;
1007 pr_err("ERROR: v4l2 capture: slave not found!\n");
1013 c->value = cam->hue;
1014 status = vidioc_int_g_ctrl(cam->sensor, c);
1015 cam->hue = c->value;
1017 pr_err("ERROR: v4l2 capture: slave not found!\n");
1021 case V4L2_CID_CONTRAST:
1023 c->value = cam->contrast;
1024 status = vidioc_int_g_ctrl(cam->sensor, c);
1025 cam->contrast = c->value;
1027 pr_err("ERROR: v4l2 capture: slave not found!\n");
1031 case V4L2_CID_SATURATION:
1033 c->value = cam->saturation;
1034 status = vidioc_int_g_ctrl(cam->sensor, c);
1035 cam->saturation = c->value;
1037 pr_err("ERROR: v4l2 capture: slave not found!\n");
1041 case V4L2_CID_RED_BALANCE:
1043 c->value = cam->red;
1044 status = vidioc_int_g_ctrl(cam->sensor, c);
1045 cam->red = c->value;
1047 pr_err("ERROR: v4l2 capture: slave not found!\n");
1051 case V4L2_CID_BLUE_BALANCE:
1053 c->value = cam->blue;
1054 status = vidioc_int_g_ctrl(cam->sensor, c);
1055 cam->blue = c->value;
1057 pr_err("ERROR: v4l2 capture: slave not found!\n");
1061 case V4L2_CID_BLACK_LEVEL:
1063 c->value = cam->ae_mode;
1064 status = vidioc_int_g_ctrl(cam->sensor, c);
1065 cam->ae_mode = c->value;
1067 pr_err("ERROR: v4l2 capture: slave not found!\n");
1072 pr_err("ERROR: v4l2 capture: unsupported ioctrl!\n");
1079 * V4L2 - set_control function
1080 * V4L2_CID_PRIVATE_BASE is the extention for IPU preprocessing.
1081 * 0 for normal operation
1082 * 1 for vertical flip
1083 * 2 for horizontal flip
1084 * 3 for horizontal and vertical flip
1085 * 4 for 90 degree rotation
1086 * @param cam structure cam_data *
1088 * @param c structure v4l2_control *
1090 * @return status 0 success, EINVAL failed
1092 static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
1095 int tmp_rotation = IPU_ROTATE_NONE;
1096 struct sensor_data *sensor_data;
1098 pr_debug("In MVC:mxc_v4l2_s_ctrl\n");
1101 case V4L2_CID_HFLIP:
1102 /* This is done by the IPU */
1103 if (c->value == 1) {
1104 if ((cam->rotation != IPU_ROTATE_VERT_FLIP) &&
1105 (cam->rotation != IPU_ROTATE_180))
1106 cam->rotation = IPU_ROTATE_HORIZ_FLIP;
1108 cam->rotation = IPU_ROTATE_180;
1110 if (cam->rotation == IPU_ROTATE_HORIZ_FLIP)
1111 cam->rotation = IPU_ROTATE_NONE;
1112 if (cam->rotation == IPU_ROTATE_180)
1113 cam->rotation = IPU_ROTATE_VERT_FLIP;
1116 case V4L2_CID_VFLIP:
1117 /* This is done by the IPU */
1118 if (c->value == 1) {
1119 if ((cam->rotation != IPU_ROTATE_HORIZ_FLIP) &&
1120 (cam->rotation != IPU_ROTATE_180))
1121 cam->rotation = IPU_ROTATE_VERT_FLIP;
1123 cam->rotation = IPU_ROTATE_180;
1125 if (cam->rotation == IPU_ROTATE_VERT_FLIP)
1126 cam->rotation = IPU_ROTATE_NONE;
1127 if (cam->rotation == IPU_ROTATE_180)
1128 cam->rotation = IPU_ROTATE_HORIZ_FLIP;
1131 case V4L2_CID_MXC_ROT:
1132 case V4L2_CID_MXC_VF_ROT:
1133 /* This is done by the IPU */
1135 case V4L2_MXC_ROTATE_NONE:
1136 tmp_rotation = IPU_ROTATE_NONE;
1138 case V4L2_MXC_ROTATE_VERT_FLIP:
1139 tmp_rotation = IPU_ROTATE_VERT_FLIP;
1141 case V4L2_MXC_ROTATE_HORIZ_FLIP:
1142 tmp_rotation = IPU_ROTATE_HORIZ_FLIP;
1144 case V4L2_MXC_ROTATE_180:
1145 tmp_rotation = IPU_ROTATE_180;
1147 case V4L2_MXC_ROTATE_90_RIGHT:
1148 tmp_rotation = IPU_ROTATE_90_RIGHT;
1150 case V4L2_MXC_ROTATE_90_RIGHT_VFLIP:
1151 tmp_rotation = IPU_ROTATE_90_RIGHT_VFLIP;
1153 case V4L2_MXC_ROTATE_90_RIGHT_HFLIP:
1154 tmp_rotation = IPU_ROTATE_90_RIGHT_HFLIP;
1156 case V4L2_MXC_ROTATE_90_LEFT:
1157 tmp_rotation = IPU_ROTATE_90_LEFT;
1162 #ifdef CONFIG_MXC_IPU_PRP_VF_SDC
1163 if (c->id == V4L2_CID_MXC_VF_ROT)
1164 cam->vf_rotation = tmp_rotation;
1166 cam->rotation = tmp_rotation;
1168 cam->rotation = tmp_rotation;
1174 cam->hue = c->value;
1175 ret = vidioc_int_s_ctrl(cam->sensor, c);
1177 pr_err("ERROR: v4l2 capture: slave not found!\n");
1181 case V4L2_CID_CONTRAST:
1183 cam->contrast = c->value;
1184 ret = vidioc_int_s_ctrl(cam->sensor, c);
1186 pr_err("ERROR: v4l2 capture: slave not found!\n");
1190 case V4L2_CID_BRIGHTNESS:
1192 cam->bright = c->value;
1193 ret = vidioc_int_s_ctrl(cam->sensor, c);
1195 pr_err("ERROR: v4l2 capture: slave not found!\n");
1199 case V4L2_CID_SATURATION:
1201 cam->saturation = c->value;
1202 ret = vidioc_int_s_ctrl(cam->sensor, c);
1204 pr_err("ERROR: v4l2 capture: slave not found!\n");
1208 case V4L2_CID_RED_BALANCE:
1210 cam->red = c->value;
1211 ret = vidioc_int_s_ctrl(cam->sensor, c);
1213 pr_err("ERROR: v4l2 capture: slave not found!\n");
1217 case V4L2_CID_BLUE_BALANCE:
1219 cam->blue = c->value;
1220 ret = vidioc_int_s_ctrl(cam->sensor, c);
1222 pr_err("ERROR: v4l2 capture: slave not found!\n");
1226 case V4L2_CID_EXPOSURE:
1228 cam->ae_mode = c->value;
1229 ret = vidioc_int_s_ctrl(cam->sensor, c);
1231 pr_err("ERROR: v4l2 capture: slave not found!\n");
1235 case V4L2_CID_MXC_FLASH:
1236 #ifdef CONFIG_MXC_IPU_V1
1237 ipu_csi_flash_strobe(true);
1240 case V4L2_CID_MXC_SWITCH_CAM:
1241 if (cam->sensor == cam->all_sensors[c->value])
1244 /* power down other cameraes before enable new one */
1245 for (i = 0; i < cam->sensor_index; i++) {
1246 if (i != c->value) {
1247 vidioc_int_dev_exit(cam->all_sensors[i]);
1248 vidioc_int_s_power(cam->all_sensors[i], 0);
1249 if (cam->mclk_on[cam->mclk_source]) {
1250 ipu_csi_enable_mclk_if(cam->ipu,
1254 cam->mclk_on[cam->mclk_source] =
1259 sensor_data = cam->all_sensors[c->value]->priv;
1260 if (sensor_data->io_init)
1261 sensor_data->io_init();
1262 cam->sensor = cam->all_sensors[c->value];
1263 cam->mclk_source = sensor_data->mclk_source;
1264 ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
1265 cam->mclk_source, true, true);
1266 cam->mclk_on[cam->mclk_source] = true;
1267 vidioc_int_s_power(cam->sensor, 1);
1268 vidioc_int_dev_init(cam->sensor);
1271 pr_debug(" default case\n");
1280 * V4L2 - mxc_v4l2_s_param function
1281 * Allows setting of capturemode and frame rate.
1283 * @param cam structure cam_data *
1284 * @param parm structure v4l2_streamparm *
1286 * @return status 0 success, EINVAL failed
1288 static int mxc_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
1290 struct v4l2_ifparm ifparm;
1291 struct v4l2_format cam_fmt;
1292 struct v4l2_streamparm currentparm;
1293 ipu_csi_signal_cfg_t csi_param;
1294 u32 current_fps, parm_fps;
1297 pr_debug("In mxc_v4l2_s_param\n");
1299 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1300 pr_err(KERN_ERR "mxc_v4l2_s_param invalid type\n");
1304 /* Stop the viewfinder */
1305 if (cam->overlay_on == true)
1308 currentparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1310 /* First check that this device can support the changes requested. */
1311 err = vidioc_int_g_parm(cam->sensor, ¤tparm);
1313 pr_err("%s: vidioc_int_g_parm returned an error %d\n",
1318 current_fps = currentparm.parm.capture.timeperframe.denominator
1319 / currentparm.parm.capture.timeperframe.numerator;
1320 parm_fps = parm->parm.capture.timeperframe.denominator
1321 / parm->parm.capture.timeperframe.numerator;
1323 pr_debug(" Current capabilities are %x\n",
1324 currentparm.parm.capture.capability);
1325 pr_debug(" Current capturemode is %d change to %d\n",
1326 currentparm.parm.capture.capturemode,
1327 parm->parm.capture.capturemode);
1328 pr_debug(" Current framerate is %d change to %d\n",
1329 current_fps, parm_fps);
1331 /* This will change any camera settings needed. */
1332 err = vidioc_int_s_parm(cam->sensor, parm);
1334 pr_err("%s: vidioc_int_s_parm returned an error %d\n",
1339 /* If resolution changed, need to re-program the CSI */
1340 /* Get new values. */
1341 vidioc_int_g_ifparm(cam->sensor, &ifparm);
1343 csi_param.data_width = 0;
1344 csi_param.clk_mode = 0;
1345 csi_param.ext_vsync = 0;
1346 csi_param.Vsync_pol = 0;
1347 csi_param.Hsync_pol = 0;
1348 csi_param.pixclk_pol = 0;
1349 csi_param.data_pol = 0;
1350 csi_param.sens_clksrc = 0;
1351 csi_param.pack_tight = 0;
1352 csi_param.force_eof = 0;
1353 csi_param.data_en_pol = 0;
1354 csi_param.data_fmt = 0;
1355 csi_param.csi = cam->csi;
1358 /*This may not work on other platforms. Check when adding a new one.*/
1359 /*The mclk clock was never set correclty in the ipu register*/
1360 /*for now we are going to use this mclk as pixel clock*/
1361 /*to set csi0_data_dest register.*/
1362 /*This is a workaround which should be fixed*/
1363 pr_debug(" clock_curr=mclk=%d\n", ifparm.u.bt656.clock_curr);
1364 if (ifparm.u.bt656.clock_curr == 0) {
1365 csi_param.clk_mode = IPU_CSI_CLK_MODE_CCIR656_INTERLACED;
1366 /*protocol bt656 use 27Mhz pixel clock */
1367 csi_param.mclk = 27000000;
1369 csi_param.clk_mode = IPU_CSI_CLK_MODE_GATED_CLK;
1372 csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;
1374 if (ifparm.u.bt656.mode == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT) {
1375 csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
1376 } else if (ifparm.u.bt656.mode
1377 == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT) {
1378 csi_param.data_width = IPU_CSI_DATA_WIDTH_10;
1380 csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
1383 csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;
1384 csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;
1385 csi_param.ext_vsync = ifparm.u.bt656.bt_sync_correct;
1387 /* if the capturemode changed, the size bounds will have changed. */
1388 cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1389 vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
1390 pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n",
1391 cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
1393 csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat;
1395 cam->crop_bounds.top = cam->crop_bounds.left = 0;
1396 cam->crop_bounds.width = cam_fmt.fmt.pix.width;
1397 cam->crop_bounds.height = cam_fmt.fmt.pix.height;
1400 * Set the default current cropped resolution to be the same with
1401 * the cropping boundary(except for tvin module).
1403 if (cam->device_type != 1) {
1404 cam->crop_current.width = cam->crop_bounds.width;
1405 cam->crop_current.height = cam->crop_bounds.height;
1408 /* This essentially loses the data at the left and bottom of the image
1409 * giving a digital zoom image, if crop_current is less than the full
1410 * size of the image. */
1411 ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
1412 cam->crop_current.height, cam->csi);
1413 ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
1414 cam->crop_current.top,
1416 ipu_csi_init_interface(cam->ipu, cam->crop_bounds.width,
1417 cam->crop_bounds.height,
1418 cam_fmt.fmt.pix.pixelformat, csi_param);
1422 if (cam->overlay_on == true)
1429 * V4L2 - mxc_v4l2_s_std function
1431 * Sets the TV standard to be used.
1433 * @param cam structure cam_data *
1434 * @param parm structure v4l2_streamparm *
1436 * @return status 0 success, EINVAL failed
1438 static int mxc_v4l2_s_std(cam_data *cam, v4l2_std_id e)
1440 printk(KERN_ERR "In mxc_v4l2_s_std %Lx\n", e);
1441 if (e == V4L2_STD_PAL) {
1442 pr_debug(" Setting standard to PAL %Lx\n", V4L2_STD_PAL);
1443 cam->standard.id = V4L2_STD_PAL;
1444 video_index = TV_PAL;
1445 } else if (e == V4L2_STD_NTSC) {
1446 pr_debug(" Setting standard to NTSC %Lx\n",
1448 /* Get rid of the white dot line in NTSC signal input */
1449 cam->standard.id = V4L2_STD_NTSC;
1450 video_index = TV_NTSC;
1452 cam->standard.id = V4L2_STD_ALL;
1453 video_index = TV_NOT_LOCKED;
1454 pr_err("ERROR: unrecognized std! %Lx (PAL=%Lx, NTSC=%Lx\n",
1455 e, V4L2_STD_PAL, V4L2_STD_NTSC);
1458 cam->standard.index = video_index;
1459 strcpy(cam->standard.name, video_fmts[video_index].name);
1460 cam->crop_bounds.width = video_fmts[video_index].raw_width;
1461 cam->crop_bounds.height = video_fmts[video_index].raw_height;
1462 cam->crop_current.width = video_fmts[video_index].active_width;
1463 cam->crop_current.height = video_fmts[video_index].active_height;
1464 cam->crop_current.top = video_fmts[video_index].active_top;
1465 cam->crop_current.left = video_fmts[video_index].active_left;
1471 * V4L2 - mxc_v4l2_g_std function
1473 * Gets the TV standard from the TV input device.
1475 * @param cam structure cam_data *
1477 * @param e structure v4l2_streamparm *
1479 * @return status 0 success, EINVAL failed
1481 static int mxc_v4l2_g_std(cam_data *cam, v4l2_std_id *e)
1483 struct v4l2_format tv_fmt;
1485 pr_debug("In mxc_v4l2_g_std\n");
1487 if (cam->device_type == 1) {
1488 /* Use this function to get what the TV-In device detects the
1489 * format to be. pixelformat is used to return the std value
1490 * since the interface has no vidioc_g_std.*/
1491 tv_fmt.type = V4L2_BUF_TYPE_PRIVATE;
1492 vidioc_int_g_fmt_cap(cam->sensor, &tv_fmt);
1494 /* If the TV-in automatically detects the standard, then if it
1495 * changes, the settings need to change. */
1496 if (cam->standard_autodetect) {
1497 if (cam->standard.id != tv_fmt.fmt.pix.pixelformat) {
1498 pr_debug("MVC: mxc_v4l2_g_std: "
1499 "Changing standard\n");
1500 mxc_v4l2_s_std(cam, tv_fmt.fmt.pix.pixelformat);
1504 *e = tv_fmt.fmt.pix.pixelformat;
1511 * Dequeue one V4L capture buffer
1513 * @param cam structure cam_data *
1514 * @param buf structure v4l2_buffer *
1516 * @return status 0 success, EINVAL invalid frame number,
1517 * ETIME timeout, ERESTARTSYS interrupted by user
1519 static int mxc_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
1522 struct mxc_v4l_frame *frame;
1523 unsigned long lock_flags;
1525 pr_debug("In MVC:mxc_v4l_dqueue\n");
1527 if (!wait_event_interruptible_timeout(cam->enc_queue,
1528 cam->enc_counter != 0, 10 * HZ)) {
1529 pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue timeout "
1533 } else if (signal_pending(current)) {
1534 pr_err("ERROR: v4l2 capture: mxc_v4l_dqueue() "
1535 "interrupt received\n");
1536 return -ERESTARTSYS;
1539 if (down_interruptible(&cam->busy_lock))
1542 spin_lock_irqsave(&cam->dqueue_int_lock, lock_flags);
1545 frame = list_entry(cam->done_q.next, struct mxc_v4l_frame, queue);
1546 list_del(cam->done_q.next);
1547 if (frame->buffer.flags & V4L2_BUF_FLAG_DONE) {
1548 frame->buffer.flags &= ~V4L2_BUF_FLAG_DONE;
1549 } else if (frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
1550 pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
1551 "Buffer not filled.\n");
1552 frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
1554 } else if ((frame->buffer.flags & 0x7) == V4L2_BUF_FLAG_MAPPED) {
1555 pr_err("ERROR: v4l2 capture: VIDIOC_DQBUF: "
1556 "Buffer not queued.\n");
1560 cam->frame[frame->index].buffer.field = cam->device_type ?
1561 V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE;
1563 buf->bytesused = cam->v2f.fmt.pix.sizeimage;
1564 buf->index = frame->index;
1565 buf->flags = frame->buffer.flags;
1566 buf->m = cam->frame[frame->index].buffer.m;
1567 buf->timestamp = cam->frame[frame->index].buffer.timestamp;
1568 buf->field = cam->frame[frame->index].buffer.field;
1569 spin_unlock_irqrestore(&cam->dqueue_int_lock, lock_flags);
1571 up(&cam->busy_lock);
1576 * V4L interface - open function
1578 * @param file structure file *
1580 * @return status 0 success, ENODEV invalid device instance,
1581 * ENODEV timeout, ERESTARTSYS interrupted by user
1583 static int mxc_v4l_open(struct file *file)
1585 struct v4l2_ifparm ifparm;
1586 struct v4l2_format cam_fmt;
1587 ipu_csi_signal_cfg_t csi_param;
1588 struct video_device *dev = video_devdata(file);
1589 cam_data *cam = video_get_drvdata(dev);
1591 struct sensor_data *sensor;
1593 pr_debug("\nIn MVC: mxc_v4l_open\n");
1594 pr_debug(" device name is %s\n", dev->name);
1597 pr_err("ERROR: v4l2 capture: Internal error, "
1598 "cam_data not found!\n");
1602 if (cam->sensor == NULL ||
1603 cam->sensor->type != v4l2_int_type_slave) {
1604 pr_err("ERROR: v4l2 capture: slave not found!\n");
1608 sensor = cam->sensor->priv;
1610 pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
1614 down(&cam->busy_lock);
1616 if (signal_pending(current))
1619 if (cam->open_count++ == 0) {
1620 wait_event_interruptible(cam->power_queue,
1621 cam->low_power == false);
1623 if (strcmp(mxc_capture_inputs[cam->current_input].name,
1625 #if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
1626 err = csi_enc_select(cam);
1628 } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
1629 "CSI IC MEM") == 0) {
1630 #if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
1631 err = prp_enc_select(cam);
1635 cam->enc_counter = 0;
1636 INIT_LIST_HEAD(&cam->ready_q);
1637 INIT_LIST_HEAD(&cam->working_q);
1638 INIT_LIST_HEAD(&cam->done_q);
1640 vidioc_int_g_ifparm(cam->sensor, &ifparm);
1642 csi_param.sens_clksrc = 0;
1644 csi_param.clk_mode = 0;
1645 csi_param.data_pol = 0;
1646 csi_param.ext_vsync = 0;
1648 csi_param.pack_tight = 0;
1649 csi_param.force_eof = 0;
1650 csi_param.data_en_pol = 0;
1652 csi_param.mclk = ifparm.u.bt656.clock_curr;
1654 csi_param.pixclk_pol = ifparm.u.bt656.latch_clk_inv;
1656 if (ifparm.u.bt656.mode
1657 == V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT)
1658 csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
1659 else if (ifparm.u.bt656.mode
1660 == V4L2_IF_TYPE_BT656_MODE_NOBT_10BIT)
1661 csi_param.data_width = IPU_CSI_DATA_WIDTH_10;
1663 csi_param.data_width = IPU_CSI_DATA_WIDTH_8;
1666 csi_param.Vsync_pol = ifparm.u.bt656.nobt_vs_inv;
1667 csi_param.Hsync_pol = ifparm.u.bt656.nobt_hs_inv;
1669 csi_param.csi = cam->csi;
1671 cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1672 vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
1674 /* Reset the sizes. Needed to prevent carryover of last
1676 cam->crop_bounds.top = cam->crop_bounds.left = 0;
1677 cam->crop_bounds.width = cam_fmt.fmt.pix.width;
1678 cam->crop_bounds.height = cam_fmt.fmt.pix.height;
1680 /* This also is the max crop size for this device. */
1681 cam->crop_defrect.top = cam->crop_defrect.left = 0;
1682 cam->crop_defrect.width = cam_fmt.fmt.pix.width;
1683 cam->crop_defrect.height = cam_fmt.fmt.pix.height;
1685 /* At this point, this is also the current image size. */
1686 cam->crop_current.top = cam->crop_current.left = 0;
1687 cam->crop_current.width = cam_fmt.fmt.pix.width;
1688 cam->crop_current.height = cam_fmt.fmt.pix.height;
1690 pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
1692 cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
1693 pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
1695 cam->crop_bounds.width, cam->crop_bounds.height);
1696 pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
1698 cam->crop_defrect.width, cam->crop_defrect.height);
1699 pr_debug("End of %s: crop_current widthxheight %d x %d\n",
1701 cam->crop_current.width, cam->crop_current.height);
1703 csi_param.data_fmt = cam_fmt.fmt.pix.pixelformat;
1704 pr_debug("On Open: Input to ipu size is %d x %d\n",
1705 cam_fmt.fmt.pix.width, cam_fmt.fmt.pix.height);
1706 ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
1707 cam->crop_current.height,
1709 ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
1710 cam->crop_current.top,
1712 ipu_csi_init_interface(cam->ipu, cam->crop_bounds.width,
1713 cam->crop_bounds.height,
1714 cam_fmt.fmt.pix.pixelformat,
1716 clk_prepare_enable(sensor->sensor_clk);
1717 vidioc_int_s_power(cam->sensor, 1);
1718 vidioc_int_init(cam->sensor);
1719 vidioc_int_dev_init(cam->sensor);
1722 file->private_data = dev;
1725 up(&cam->busy_lock);
1730 * V4L interface - close function
1732 * @param file struct file *
1736 static int mxc_v4l_close(struct file *file)
1738 struct video_device *dev = video_devdata(file);
1740 cam_data *cam = video_get_drvdata(dev);
1741 struct sensor_data *sensor;
1742 pr_debug("In MVC:mxc_v4l_close\n");
1745 pr_err("ERROR: v4l2 capture: Internal error, "
1746 "cam_data not found!\n");
1751 pr_err("%s: Internal error, camera is not found!\n", __func__);
1755 sensor = cam->sensor->priv;
1757 pr_err("%s: Internal error, sensor_data is not found!\n", __func__);
1761 down(&cam->busy_lock);
1763 /* for the case somebody hit the ctrl C */
1764 if (cam->overlay_pid == current->pid && cam->overlay_on) {
1765 err = stop_preview(cam);
1766 cam->overlay_on = false;
1768 if (cam->capture_pid == current->pid) {
1769 err |= mxc_streamoff(cam);
1770 wake_up_interruptible(&cam->enc_queue);
1773 if (--cam->open_count == 0) {
1774 vidioc_int_s_power(cam->sensor, 0);
1775 clk_disable_unprepare(sensor->sensor_clk);
1776 wait_event_interruptible(cam->power_queue,
1777 cam->low_power == false);
1778 pr_debug("mxc_v4l_close: release resource\n");
1780 if (strcmp(mxc_capture_inputs[cam->current_input].name,
1782 #if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
1783 err |= csi_enc_deselect(cam);
1785 } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
1786 "CSI IC MEM") == 0) {
1787 #if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
1788 err |= prp_enc_deselect(cam);
1792 mxc_free_frame_buf(cam);
1793 file->private_data = NULL;
1796 wake_up_interruptible(&cam->enc_queue);
1797 mxc_free_frames(cam);
1801 up(&cam->busy_lock);
1806 #if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC) || \
1807 defined(CONFIG_MXC_IPU_PRP_ENC_MODULE) || \
1808 defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
1810 * V4L interface - read function
1812 * @param file struct file *
1813 * @param read buf char *
1814 * @param count size_t
1815 * @param ppos structure loff_t *
1817 * @return bytes read
1819 static ssize_t mxc_v4l_read(struct file *file, char *buf, size_t count,
1824 struct video_device *dev = video_devdata(file);
1825 cam_data *cam = video_get_drvdata(dev);
1827 if (down_interruptible(&cam->busy_lock))
1830 /* Stop the viewfinder */
1831 if (cam->overlay_on == true)
1834 v_address[0] = dma_alloc_coherent(0,
1835 PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
1837 GFP_DMA | GFP_KERNEL);
1839 v_address[1] = dma_alloc_coherent(0,
1840 PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),
1842 GFP_DMA | GFP_KERNEL);
1844 if (!v_address[0] || !v_address[1]) {
1849 err = prp_still_select(cam);
1855 cam->still_counter = 0;
1856 err = cam->csi_start(cam);
1862 if (!wait_event_interruptible_timeout(cam->still_queue,
1863 cam->still_counter != 0,
1865 pr_err("ERROR: v4l2 capture: mxc_v4l_read timeout counter %x\n",
1866 cam->still_counter);
1870 err = copy_to_user(buf, v_address[1], cam->v2f.fmt.pix.sizeimage);
1873 prp_still_deselect(cam);
1876 if (v_address[0] != 0)
1877 dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address[0],
1879 if (v_address[1] != 0)
1880 dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address[1],
1883 cam->still_buf[0] = cam->still_buf[1] = 0;
1885 if (cam->overlay_on == true)
1888 up(&cam->busy_lock);
1892 return cam->v2f.fmt.pix.sizeimage - err;
1897 * V4L interface - ioctl function
1899 * @param file struct file*
1901 * @param ioctlnr unsigned int
1905 * @return 0 success, ENODEV for invalid device instance,
1906 * -1 for other errors.
1908 static long mxc_v4l_do_ioctl(struct file *file,
1909 unsigned int ioctlnr, void *arg)
1911 struct video_device *dev = video_devdata(file);
1912 cam_data *cam = video_get_drvdata(dev);
1914 unsigned long lock_flags;
1916 pr_debug("In MVC: mxc_v4l_do_ioctl %x\n", ioctlnr);
1917 wait_event_interruptible(cam->power_queue, cam->low_power == false);
1918 /* make this _really_ smp-safe */
1919 if (ioctlnr != VIDIOC_DQBUF)
1920 if (down_interruptible(&cam->busy_lock))
1925 * V4l2 VIDIOC_QUERYCAP ioctl
1927 case VIDIOC_QUERYCAP: {
1928 struct v4l2_capability *cap = arg;
1929 pr_debug(" case VIDIOC_QUERYCAP\n");
1930 strcpy(cap->driver, "mxc_v4l2");
1931 cap->version = KERNEL_VERSION(0, 1, 11);
1932 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
1933 V4L2_CAP_VIDEO_OVERLAY |
1934 V4L2_CAP_STREAMING |
1936 cap->card[0] = '\0';
1937 cap->bus_info[0] = '\0';
1942 * V4l2 VIDIOC_G_FMT ioctl
1944 case VIDIOC_G_FMT: {
1945 struct v4l2_format *gf = arg;
1946 pr_debug(" case VIDIOC_G_FMT\n");
1947 retval = mxc_v4l2_g_fmt(cam, gf);
1952 * V4l2 VIDIOC_S_FMT ioctl
1954 case VIDIOC_S_FMT: {
1955 struct v4l2_format *sf = arg;
1956 pr_debug(" case VIDIOC_S_FMT\n");
1957 retval = mxc_v4l2_s_fmt(cam, sf);
1962 * V4l2 VIDIOC_REQBUFS ioctl
1964 case VIDIOC_REQBUFS: {
1965 struct v4l2_requestbuffers *req = arg;
1966 pr_debug(" case VIDIOC_REQBUFS\n");
1968 if (req->count > FRAME_NUM) {
1969 pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
1970 "not enough buffers\n");
1971 req->count = FRAME_NUM;
1974 if ((req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
1975 pr_err("ERROR: v4l2 capture: VIDIOC_REQBUFS: "
1976 "wrong buffer type\n");
1982 if (req->memory & V4L2_MEMORY_MMAP) {
1983 mxc_free_frame_buf(cam);
1984 retval = mxc_allocate_frame_buf(cam, req->count);
1990 * V4l2 VIDIOC_QUERYBUF ioctl
1992 case VIDIOC_QUERYBUF: {
1993 struct v4l2_buffer *buf = arg;
1994 int index = buf->index;
1995 pr_debug(" case VIDIOC_QUERYBUF\n");
1997 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1998 pr_err("ERROR: v4l2 capture: "
1999 "VIDIOC_QUERYBUFS: "
2000 "wrong buffer type\n");
2005 if (buf->memory & V4L2_MEMORY_MMAP) {
2006 memset(buf, 0, sizeof(buf));
2010 down(&cam->param_lock);
2011 if (buf->memory & V4L2_MEMORY_USERPTR) {
2012 mxc_v4l2_release_bufs(cam);
2013 retval = mxc_v4l2_prepare_bufs(cam, buf);
2016 if (buf->memory & V4L2_MEMORY_MMAP)
2017 retval = mxc_v4l2_buffer_status(cam, buf);
2018 up(&cam->param_lock);
2023 * V4l2 VIDIOC_QBUF ioctl
2026 struct v4l2_buffer *buf = arg;
2027 int index = buf->index;
2028 pr_debug(" case VIDIOC_QBUF\n");
2030 spin_lock_irqsave(&cam->queue_int_lock, lock_flags);
2031 if ((cam->frame[index].buffer.flags & 0x7) ==
2032 V4L2_BUF_FLAG_MAPPED) {
2033 cam->frame[index].buffer.flags |=
2034 V4L2_BUF_FLAG_QUEUED;
2035 list_add_tail(&cam->frame[index].queue,
2037 } else if (cam->frame[index].buffer.
2038 flags & V4L2_BUF_FLAG_QUEUED) {
2039 pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
2040 "buffer already queued\n");
2042 } else if (cam->frame[index].buffer.
2043 flags & V4L2_BUF_FLAG_DONE) {
2044 pr_err("ERROR: v4l2 capture: VIDIOC_QBUF: "
2045 "overwrite done buffer.\n");
2046 cam->frame[index].buffer.flags &=
2047 ~V4L2_BUF_FLAG_DONE;
2048 cam->frame[index].buffer.flags |=
2049 V4L2_BUF_FLAG_QUEUED;
2053 buf->flags = cam->frame[index].buffer.flags;
2054 spin_unlock_irqrestore(&cam->queue_int_lock, lock_flags);
2059 * V4l2 VIDIOC_DQBUF ioctl
2061 case VIDIOC_DQBUF: {
2062 struct v4l2_buffer *buf = arg;
2063 pr_debug(" case VIDIOC_DQBUF\n");
2065 if ((cam->enc_counter == 0) &&
2066 (file->f_flags & O_NONBLOCK)) {
2071 retval = mxc_v4l_dqueue(cam, buf);
2076 * V4l2 VIDIOC_STREAMON ioctl
2078 case VIDIOC_STREAMON: {
2079 pr_debug(" case VIDIOC_STREAMON\n");
2080 retval = mxc_streamon(cam);
2085 * V4l2 VIDIOC_STREAMOFF ioctl
2087 case VIDIOC_STREAMOFF: {
2088 pr_debug(" case VIDIOC_STREAMOFF\n");
2089 retval = mxc_streamoff(cam);
2094 * V4l2 VIDIOC_G_CTRL ioctl
2096 case VIDIOC_G_CTRL: {
2097 pr_debug(" case VIDIOC_G_CTRL\n");
2098 retval = mxc_v4l2_g_ctrl(cam, arg);
2103 * V4l2 VIDIOC_S_CTRL ioctl
2105 case VIDIOC_S_CTRL: {
2106 pr_debug(" case VIDIOC_S_CTRL\n");
2107 retval = mxc_v4l2_s_ctrl(cam, arg);
2112 * V4l2 VIDIOC_CROPCAP ioctl
2114 case VIDIOC_CROPCAP: {
2115 struct v4l2_cropcap *cap = arg;
2116 pr_debug(" case VIDIOC_CROPCAP\n");
2117 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
2118 cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
2122 cap->bounds = cam->crop_bounds;
2123 cap->defrect = cam->crop_defrect;
2128 * V4l2 VIDIOC_G_CROP ioctl
2130 case VIDIOC_G_CROP: {
2131 struct v4l2_crop *crop = arg;
2132 pr_debug(" case VIDIOC_G_CROP\n");
2134 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
2135 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
2139 crop->c = cam->crop_current;
2144 * V4l2 VIDIOC_S_CROP ioctl
2146 case VIDIOC_S_CROP: {
2147 struct v4l2_crop *crop = arg;
2148 struct v4l2_rect *b = &cam->crop_bounds;
2149 pr_debug(" case VIDIOC_S_CROP\n");
2151 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
2152 crop->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) {
2157 crop->c.top = (crop->c.top < b->top) ? b->top
2159 if (crop->c.top > b->top + b->height)
2160 crop->c.top = b->top + b->height - 1;
2161 if (crop->c.height > b->top + b->height - crop->c.top)
2163 b->top + b->height - crop->c.top;
2165 crop->c.left = (crop->c.left < b->left) ? b->left
2167 if (crop->c.left > b->left + b->width)
2168 crop->c.left = b->left + b->width - 1;
2169 if (crop->c.width > b->left - crop->c.left + b->width)
2171 b->left - crop->c.left + b->width;
2173 crop->c.width -= crop->c.width % 8;
2174 crop->c.left -= crop->c.left % 4;
2175 cam->crop_current = crop->c;
2177 pr_debug(" Cropping Input to ipu size %d x %d\n",
2178 cam->crop_current.width,
2179 cam->crop_current.height);
2180 ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
2181 cam->crop_current.height,
2183 ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
2184 cam->crop_current.top,
2190 * V4l2 VIDIOC_OVERLAY ioctl
2192 case VIDIOC_OVERLAY: {
2194 pr_debug(" VIDIOC_OVERLAY on=%d\n", *on);
2196 cam->overlay_on = true;
2197 cam->overlay_pid = current->pid;
2198 retval = start_preview(cam);
2201 retval = stop_preview(cam);
2202 cam->overlay_on = false;
2208 * V4l2 VIDIOC_G_FBUF ioctl
2210 case VIDIOC_G_FBUF: {
2211 struct v4l2_framebuffer *fb = arg;
2212 pr_debug(" case VIDIOC_G_FBUF\n");
2214 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY;
2219 * V4l2 VIDIOC_S_FBUF ioctl
2221 case VIDIOC_S_FBUF: {
2222 struct v4l2_framebuffer *fb = arg;
2223 pr_debug(" case VIDIOC_S_FBUF\n");
2228 case VIDIOC_G_PARM: {
2229 struct v4l2_streamparm *parm = arg;
2230 pr_debug(" case VIDIOC_G_PARM\n");
2232 retval = vidioc_int_g_parm(cam->sensor, parm);
2234 pr_err("ERROR: v4l2 capture: slave not found!\n");
2240 case VIDIOC_S_PARM: {
2241 struct v4l2_streamparm *parm = arg;
2242 pr_debug(" case VIDIOC_S_PARM\n");
2244 retval = mxc_v4l2_s_param(cam, parm);
2246 pr_err("ERROR: v4l2 capture: slave not found!\n");
2252 /* linux v4l2 bug, kernel c0485619 user c0405619 */
2253 case VIDIOC_ENUMSTD: {
2254 struct v4l2_standard *e = arg;
2255 pr_debug(" case VIDIOC_ENUMSTD\n");
2260 case VIDIOC_G_STD: {
2261 v4l2_std_id *e = arg;
2262 pr_debug(" case VIDIOC_G_STD\n");
2264 retval = mxc_v4l2_g_std(cam, e);
2266 pr_err("ERROR: v4l2 capture: slave not found!\n");
2272 case VIDIOC_S_STD: {
2273 v4l2_std_id *e = arg;
2274 pr_debug(" case VIDIOC_S_STD\n");
2275 retval = mxc_v4l2_s_std(cam, *e);
2280 case VIDIOC_ENUMOUTPUT: {
2281 struct v4l2_output *output = arg;
2282 pr_debug(" case VIDIOC_ENUMOUTPUT\n");
2283 if (output->index >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) {
2287 *output = mxc_capture_outputs[output->index];
2291 case VIDIOC_G_OUTPUT: {
2292 int *p_output_num = arg;
2293 pr_debug(" case VIDIOC_G_OUTPUT\n");
2294 *p_output_num = cam->output;
2298 case VIDIOC_S_OUTPUT: {
2299 int *p_output_num = arg;
2300 pr_debug(" case VIDIOC_S_OUTPUT\n");
2301 if (*p_output_num >= MXC_V4L2_CAPTURE_NUM_OUTPUTS) {
2305 cam->output = *p_output_num;
2309 case VIDIOC_ENUMINPUT: {
2310 struct v4l2_input *input = arg;
2311 pr_debug(" case VIDIOC_ENUMINPUT\n");
2312 if (input->index >= MXC_V4L2_CAPTURE_NUM_INPUTS) {
2316 *input = mxc_capture_inputs[input->index];
2320 case VIDIOC_G_INPUT: {
2322 pr_debug(" case VIDIOC_G_INPUT\n");
2323 *index = cam->current_input;
2327 case VIDIOC_S_INPUT: {
2329 pr_debug(" case VIDIOC_S_INPUT\n");
2330 if (*index >= MXC_V4L2_CAPTURE_NUM_INPUTS) {
2335 if (*index == cam->current_input)
2338 if ((mxc_capture_inputs[cam->current_input].status &
2339 V4L2_IN_ST_NO_POWER) == 0) {
2340 retval = mxc_streamoff(cam);
2343 mxc_capture_inputs[cam->current_input].status |=
2344 V4L2_IN_ST_NO_POWER;
2347 if (strcmp(mxc_capture_inputs[*index].name, "CSI MEM") == 0) {
2348 #if defined(CONFIG_MXC_IPU_CSI_ENC) || defined(CONFIG_MXC_IPU_CSI_ENC_MODULE)
2349 retval = csi_enc_select(cam);
2353 } else if (strcmp(mxc_capture_inputs[*index].name,
2354 "CSI IC MEM") == 0) {
2355 #if defined(CONFIG_MXC_IPU_PRP_ENC) || defined(CONFIG_MXC_IPU_PRP_ENC_MODULE)
2356 retval = prp_enc_select(cam);
2362 mxc_capture_inputs[*index].status &= ~V4L2_IN_ST_NO_POWER;
2363 cam->current_input = *index;
2366 case VIDIOC_ENUM_FMT: {
2367 struct v4l2_fmtdesc *f = arg;
2369 retval = vidioc_int_enum_fmt_cap(cam->sensor, f);
2371 pr_err("ERROR: v4l2 capture: slave not found!\n");
2376 case VIDIOC_ENUM_FRAMESIZES: {
2377 struct v4l2_frmsizeenum *fsize = arg;
2379 retval = vidioc_int_enum_framesizes(cam->sensor, fsize);
2381 pr_err("ERROR: v4l2 capture: slave not found!\n");
2386 case VIDIOC_DBG_G_CHIP_IDENT: {
2387 struct v4l2_dbg_chip_ident *p = arg;
2388 p->ident = V4L2_IDENT_NONE;
2391 retval = vidioc_int_g_chip_ident(cam->sensor, (int *)p);
2393 pr_err("ERROR: v4l2 capture: slave not found!\n");
2398 case VIDIOC_TRY_FMT:
2399 case VIDIOC_QUERYCTRL:
2400 case VIDIOC_G_TUNER:
2401 case VIDIOC_S_TUNER:
2402 case VIDIOC_G_FREQUENCY:
2403 case VIDIOC_S_FREQUENCY:
2405 pr_debug(" case default or not supported\n");
2410 if (ioctlnr != VIDIOC_DQBUF)
2411 up(&cam->busy_lock);
2416 * V4L interface - ioctl function
2420 static long mxc_v4l_ioctl(struct file *file, unsigned int cmd,
2423 pr_debug("In MVC:mxc_v4l_ioctl\n");
2424 return video_usercopy(file, cmd, arg, mxc_v4l_do_ioctl);
2428 * V4L interface - mmap function
2430 * @param file structure file *
2432 * @param vma structure vm_area_struct *
2434 * @return status 0 Success, EINTR busy lock error, ENOBUFS remap_page error
2436 static int mxc_mmap(struct file *file, struct vm_area_struct *vma)
2438 struct video_device *dev = video_devdata(file);
2441 cam_data *cam = video_get_drvdata(dev);
2443 pr_debug("In MVC:mxc_mmap\n");
2444 pr_debug(" pgoff=0x%lx, start=0x%lx, end=0x%lx\n",
2445 vma->vm_pgoff, vma->vm_start, vma->vm_end);
2447 /* make this _really_ smp-safe */
2448 if (down_interruptible(&cam->busy_lock))
2451 size = vma->vm_end - vma->vm_start;
2452 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
2454 if (remap_pfn_range(vma, vma->vm_start,
2455 vma->vm_pgoff, size, vma->vm_page_prot)) {
2456 pr_err("ERROR: v4l2 capture: mxc_mmap: "
2457 "remap_pfn_range failed\n");
2462 vma->vm_flags &= ~VM_IO; /* using shared anonymous pages */
2465 up(&cam->busy_lock);
2470 * V4L interface - poll function
2472 * @param file structure file *
2474 * @param wait structure poll_table_struct *
2476 * @return status POLLIN | POLLRDNORM
2478 static unsigned int mxc_poll(struct file *file, struct poll_table_struct *wait)
2480 struct video_device *dev = video_devdata(file);
2481 cam_data *cam = video_get_drvdata(dev);
2482 wait_queue_head_t *queue = NULL;
2483 int res = POLLIN | POLLRDNORM;
2485 pr_debug("In MVC:mxc_poll\n");
2487 if (down_interruptible(&cam->busy_lock))
2490 queue = &cam->enc_queue;
2491 poll_wait(file, queue, wait);
2493 up(&cam->busy_lock);
2499 * This structure defines the functions to be called in this driver.
2501 static struct v4l2_file_operations mxc_v4l_fops = {
2502 .owner = THIS_MODULE,
2503 .open = mxc_v4l_open,
2504 .release = mxc_v4l_close,
2505 .read = mxc_v4l_read,
2506 .ioctl = mxc_v4l_ioctl,
2511 static struct video_device mxc_v4l_template = {
2512 .name = "Mxc Camera",
2513 .fops = &mxc_v4l_fops,
2514 .release = video_device_release,
2518 * This function can be used to release any platform data on closing.
2520 static void camera_platform_release(struct device *device)
2525 * Camera V4l2 callback function.
2529 * @param dev void device structure
2533 static void camera_callback(u32 mask, void *dev)
2535 struct mxc_v4l_frame *done_frame;
2536 struct mxc_v4l_frame *ready_frame;
2537 struct timeval cur_time;
2539 cam_data *cam = (cam_data *) dev;
2543 pr_debug("In MVC:camera_callback\n");
2545 spin_lock(&cam->queue_int_lock);
2546 spin_lock(&cam->dqueue_int_lock);
2547 if (!list_empty(&cam->working_q)) {
2548 do_gettimeofday(&cur_time);
2550 done_frame = list_entry(cam->working_q.next,
2551 struct mxc_v4l_frame,
2554 if (done_frame->ipu_buf_num != cam->local_buf_num)
2558 * Set the current time to done frame buffer's
2559 * timestamp. Users can use this information to judge
2560 * the frame's usage.
2562 done_frame->buffer.timestamp = cur_time;
2564 if (done_frame->buffer.flags & V4L2_BUF_FLAG_QUEUED) {
2565 done_frame->buffer.flags |= V4L2_BUF_FLAG_DONE;
2566 done_frame->buffer.flags &= ~V4L2_BUF_FLAG_QUEUED;
2568 /* Added to the done queue */
2569 list_del(cam->working_q.next);
2570 list_add_tail(&done_frame->queue, &cam->done_q);
2572 /* Wake up the queue */
2574 wake_up_interruptible(&cam->enc_queue);
2576 pr_err("ERROR: v4l2 capture: camera_callback: "
2577 "buffer not queued\n");
2581 if (!list_empty(&cam->ready_q)) {
2582 ready_frame = list_entry(cam->ready_q.next,
2583 struct mxc_v4l_frame,
2585 if (cam->enc_update_eba)
2586 if (cam->enc_update_eba(cam->ipu,
2587 ready_frame->buffer.m.offset,
2588 &cam->ping_pong_csi) == 0) {
2589 list_del(cam->ready_q.next);
2590 list_add_tail(&ready_frame->queue,
2592 ready_frame->ipu_buf_num = cam->local_buf_num;
2595 if (cam->enc_update_eba)
2596 cam->enc_update_eba(
2597 cam->ipu, cam->dummy_frame.buffer.m.offset,
2598 &cam->ping_pong_csi);
2601 cam->local_buf_num = (cam->local_buf_num == 0) ? 1 : 0;
2602 spin_unlock(&cam->dqueue_int_lock);
2603 spin_unlock(&cam->queue_int_lock);
2609 * initialize cam_data structure
2611 * @param cam structure cam_data *
2613 * @return status 0 Success
2615 static int init_camera_struct(cam_data *cam, struct platform_device *pdev)
2617 const struct of_device_id *of_id =
2618 of_match_device(mxc_v4l2_dt_ids, &pdev->dev);
2619 struct device_node *np = pdev->dev.of_node;
2620 int ipu_id, csi_id, mclk_source;
2623 pr_debug("In MVC: init_camera_struct\n");
2625 ret = of_property_read_u32(np, "ipu_id", &ipu_id);
2627 dev_err(&pdev->dev, "ipu_id missing or invalid\n");
2631 ret = of_property_read_u32(np, "csi_id", &csi_id);
2633 dev_err(&pdev->dev, "csi_id missing or invalid\n");
2637 ret = of_property_read_u32(np, "mclk_source", &mclk_source);
2639 dev_err(&pdev->dev, "sensor mclk missing or invalid\n");
2643 /* Default everything to 0 */
2644 memset(cam, 0, sizeof(cam_data));
2646 /* get devtype to distinguish if the cpu is imx5 or imx6
2647 * IMX5_V4L2 specify the cpu is imx5
2648 * IMX6_V4L2 specify the cpu is imx6q or imx6sdl
2651 pdev->id_entry = of_id->data;
2652 cam->devtype = pdev->id_entry->driver_data;
2654 cam->ipu = ipu_get_soc(ipu_id);
2655 if (cam->ipu == NULL) {
2656 pr_err("ERROR: v4l2 capture: failed to get ipu\n");
2658 } else if (cam->ipu == ERR_PTR(-ENODEV)) {
2659 pr_err("ERROR: v4l2 capture: get invalid ipu\n");
2663 init_MUTEX(&cam->param_lock);
2664 init_MUTEX(&cam->busy_lock);
2666 cam->video_dev = video_device_alloc();
2667 if (cam->video_dev == NULL)
2670 *(cam->video_dev) = mxc_v4l_template;
2672 video_set_drvdata(cam->video_dev, cam);
2673 dev_set_drvdata(&pdev->dev, (void *)cam);
2674 cam->video_dev->minor = -1;
2676 init_waitqueue_head(&cam->enc_queue);
2677 init_waitqueue_head(&cam->still_queue);
2679 /* setup cropping */
2680 cam->crop_bounds.left = 0;
2681 cam->crop_bounds.width = 640;
2682 cam->crop_bounds.top = 0;
2683 cam->crop_bounds.height = 480;
2684 cam->crop_current = cam->crop_defrect = cam->crop_bounds;
2685 ipu_csi_set_window_size(cam->ipu, cam->crop_current.width,
2686 cam->crop_current.height, cam->csi);
2687 ipu_csi_set_window_pos(cam->ipu, cam->crop_current.left,
2688 cam->crop_current.top, cam->csi);
2689 cam->streamparm.parm.capture.capturemode = 0;
2691 cam->standard.index = 0;
2692 cam->standard.id = V4L2_STD_UNKNOWN;
2693 cam->standard.frameperiod.denominator = 30;
2694 cam->standard.frameperiod.numerator = 1;
2695 cam->standard.framelines = 480;
2696 cam->standard_autodetect = true;
2697 cam->streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2698 cam->streamparm.parm.capture.timeperframe = cam->standard.frameperiod;
2699 cam->streamparm.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
2700 cam->overlay_on = false;
2701 cam->capture_on = false;
2702 cam->v4l2_fb.flags = V4L2_FBUF_FLAG_OVERLAY;
2704 cam->v2f.fmt.pix.sizeimage = 352 * 288 * 3 / 2;
2705 cam->v2f.fmt.pix.bytesperline = 288 * 3 / 2;
2706 cam->v2f.fmt.pix.width = 288;
2707 cam->v2f.fmt.pix.height = 352;
2708 cam->v2f.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420;
2709 cam->win.w.width = 160;
2710 cam->win.w.height = 160;
2711 cam->win.w.left = 0;
2714 cam->ipu_id = ipu_id;
2716 cam->mclk_source = mclk_source;
2717 cam->mclk_on[cam->mclk_source] = false;
2719 cam->enc_callback = camera_callback;
2720 init_waitqueue_head(&cam->power_queue);
2721 spin_lock_init(&cam->queue_int_lock);
2722 spin_lock_init(&cam->dqueue_int_lock);
2724 cam->self = kmalloc(sizeof(struct v4l2_int_device), GFP_KERNEL);
2725 cam->self->module = THIS_MODULE;
2726 sprintf(cam->self->name, "mxc_v4l2_cap%d", cam->csi);
2727 cam->self->type = v4l2_int_type_master;
2728 cam->self->u.master = &mxc_v4l2_master;
2733 static ssize_t show_streaming(struct device *dev,
2734 struct device_attribute *attr, char *buf)
2736 struct video_device *video_dev = container_of(dev,
2737 struct video_device, dev);
2738 cam_data *cam = video_get_drvdata(video_dev);
2740 if (cam->capture_on)
2741 return sprintf(buf, "stream on\n");
2743 return sprintf(buf, "stream off\n");
2745 static DEVICE_ATTR(fsl_v4l2_capture_property, S_IRUGO, show_streaming, NULL);
2747 static ssize_t show_overlay(struct device *dev,
2748 struct device_attribute *attr, char *buf)
2750 struct video_device *video_dev = container_of(dev,
2751 struct video_device, dev);
2752 cam_data *cam = video_get_drvdata(video_dev);
2754 if (cam->overlay_on)
2755 return sprintf(buf, "overlay on\n");
2757 return sprintf(buf, "overlay off\n");
2759 static DEVICE_ATTR(fsl_v4l2_overlay_property, S_IRUGO, show_overlay, NULL);
2761 static ssize_t show_csi(struct device *dev,
2762 struct device_attribute *attr, char *buf)
2764 struct video_device *video_dev = container_of(dev,
2765 struct video_device, dev);
2766 cam_data *cam = video_get_drvdata(video_dev);
2768 return sprintf(buf, "ipu%d_csi%d\n", cam->ipu_id, cam->csi);
2770 static DEVICE_ATTR(fsl_csi_property, S_IRUGO, show_csi, NULL);
2773 * This function is called to probe the devices if registered.
2775 * @param pdev the device structure used to give information on which device
2778 * @return The function returns 0 on success and -1 on failure.
2780 static int mxc_v4l2_probe(struct platform_device *pdev)
2782 /* Create cam and initialize it. */
2783 cam_data *cam = kmalloc(sizeof(cam_data), GFP_KERNEL);
2785 pr_err("ERROR: v4l2 capture: failed to register camera\n");
2789 init_camera_struct(cam, pdev);
2790 pdev->dev.release = camera_platform_release;
2792 /* Set up the v4l2 device and register it*/
2793 cam->self->priv = cam;
2794 v4l2_int_device_register(cam->self);
2796 /* register v4l video device */
2797 if (video_register_device(cam->video_dev, VFL_TYPE_GRABBER, video_nr)
2801 pr_err("ERROR: v4l2 capture: video_register_device failed\n");
2804 pr_debug(" Video device registered: %s #%d\n",
2805 cam->video_dev->name, cam->video_dev->minor);
2807 if (device_create_file(&cam->video_dev->dev,
2808 &dev_attr_fsl_v4l2_capture_property))
2809 dev_err(&pdev->dev, "Error on creating sysfs file"
2812 if (device_create_file(&cam->video_dev->dev,
2813 &dev_attr_fsl_v4l2_overlay_property))
2814 dev_err(&pdev->dev, "Error on creating sysfs file"
2817 if (device_create_file(&cam->video_dev->dev,
2818 &dev_attr_fsl_csi_property))
2819 dev_err(&pdev->dev, "Error on creating sysfs file"
2820 " for csi number\n");
2826 * This function is called to remove the devices when device unregistered.
2828 * @param pdev the device structure used to give information on which device
2831 * @return The function returns 0 on success and -1 on failure.
2833 static int mxc_v4l2_remove(struct platform_device *pdev)
2835 cam_data *cam = (cam_data *)platform_get_drvdata(pdev);
2836 if (cam->open_count) {
2837 pr_err("ERROR: v4l2 capture:camera open "
2838 "-- setting ops to NULL\n");
2841 device_remove_file(&cam->video_dev->dev,
2842 &dev_attr_fsl_v4l2_capture_property);
2843 device_remove_file(&cam->video_dev->dev,
2844 &dev_attr_fsl_v4l2_overlay_property);
2845 device_remove_file(&cam->video_dev->dev,
2846 &dev_attr_fsl_csi_property);
2848 pr_info("V4L2 freeing image input device\n");
2849 v4l2_int_device_unregister(cam->self);
2850 video_unregister_device(cam->video_dev);
2852 mxc_free_frame_buf(cam);
2856 pr_info("V4L2 unregistering video\n");
2861 * This function is called to put the sensor in a low power state.
2862 * Refer to the document driver-model/driver.txt in the kernel source tree
2863 * for more information.
2865 * @param pdev the device structure used to give information on which I2C
2867 * @param state the power state the device is entering
2869 * @return The function returns 0 on success and -1 on failure.
2871 static int mxc_v4l2_suspend(struct platform_device *pdev, pm_message_t state)
2873 cam_data *cam = platform_get_drvdata(pdev);
2875 pr_debug("In MVC:mxc_v4l2_suspend\n");
2880 down(&cam->busy_lock);
2882 cam->low_power = true;
2884 if (cam->overlay_on == true)
2886 if ((cam->capture_on == true) && cam->enc_disable)
2887 cam->enc_disable(cam);
2889 if (cam->sensor && cam->open_count) {
2890 if (cam->mclk_on[cam->mclk_source]) {
2891 ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
2894 cam->mclk_on[cam->mclk_source] = false;
2896 vidioc_int_s_power(cam->sensor, 0);
2899 up(&cam->busy_lock);
2905 * This function is called to bring the sensor back from a low power state.
2906 * Refer to the document driver-model/driver.txt in the kernel source tree
2907 * for more information.
2909 * @param pdev the device structure
2911 * @return The function returns 0 on success and -1 on failure
2913 static int mxc_v4l2_resume(struct platform_device *pdev)
2915 cam_data *cam = platform_get_drvdata(pdev);
2917 pr_debug("In MVC:mxc_v4l2_resume\n");
2922 down(&cam->busy_lock);
2924 cam->low_power = false;
2925 wake_up_interruptible(&cam->power_queue);
2927 if (cam->sensor && cam->open_count) {
2928 vidioc_int_s_power(cam->sensor, 1);
2930 if (!cam->mclk_on[cam->mclk_source]) {
2931 ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C,
2934 cam->mclk_on[cam->mclk_source] = true;
2938 if (cam->overlay_on == true)
2940 if (cam->capture_on == true)
2943 up(&cam->busy_lock);
2949 * This structure contains pointers to the power management callback functions.
2951 static struct platform_driver mxc_v4l2_driver = {
2953 .name = "mxc_v4l2_capture",
2954 .owner = THIS_MODULE,
2955 .of_match_table = mxc_v4l2_dt_ids,
2957 .id_table = imx_v4l2_devtype,
2958 .probe = mxc_v4l2_probe,
2959 .remove = mxc_v4l2_remove,
2960 .suspend = mxc_v4l2_suspend,
2961 .resume = mxc_v4l2_resume,
2966 * Initializes the camera driver.
2968 static int mxc_v4l2_master_attach(struct v4l2_int_device *slave)
2970 cam_data *cam = slave->u.slave->master->priv;
2971 struct v4l2_format cam_fmt;
2973 struct sensor_data *sdata = slave->priv;
2975 pr_debug("In MVC: mxc_v4l2_master_attach\n");
2976 pr_debug(" slave.name = %s\n", slave->name);
2977 pr_debug(" master.name = %s\n", slave->u.slave->master->name);
2979 if (slave == NULL) {
2980 pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
2984 if (sdata->csi != cam->csi) {
2985 pr_debug("%s: csi doesn't match\n", __func__);
2989 cam->sensor = slave;
2991 if (cam->sensor_index < MXC_SENSOR_NUM) {
2992 cam->all_sensors[cam->sensor_index] = slave;
2993 cam->sensor_index++;
2995 pr_err("ERROR: v4l2 capture: slave number exceeds the maximum.\n");
2999 for (i = 0; i < cam->sensor_index; i++) {
3000 vidioc_int_dev_exit(cam->all_sensors[i]);
3001 vidioc_int_s_power(cam->all_sensors[i], 0);
3004 cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3005 vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
3007 /* Used to detect TV in (type 1) vs. camera (type 0)*/
3008 cam->device_type = cam_fmt.fmt.pix.priv;
3010 /* Set the input size to the ipu for this device */
3011 cam->crop_bounds.top = cam->crop_bounds.left = 0;
3012 cam->crop_bounds.width = cam_fmt.fmt.pix.width;
3013 cam->crop_bounds.height = cam_fmt.fmt.pix.height;
3015 /* This also is the max crop size for this device. */
3016 cam->crop_defrect.top = cam->crop_defrect.left = 0;
3017 cam->crop_defrect.width = cam_fmt.fmt.pix.width;
3018 cam->crop_defrect.height = cam_fmt.fmt.pix.height;
3020 /* At this point, this is also the current image size. */
3021 cam->crop_current.top = cam->crop_current.left = 0;
3022 cam->crop_current.width = cam_fmt.fmt.pix.width;
3023 cam->crop_current.height = cam_fmt.fmt.pix.height;
3025 pr_debug("End of %s: v2f pix widthxheight %d x %d\n",
3027 cam->v2f.fmt.pix.width, cam->v2f.fmt.pix.height);
3028 pr_debug("End of %s: crop_bounds widthxheight %d x %d\n",
3030 cam->crop_bounds.width, cam->crop_bounds.height);
3031 pr_debug("End of %s: crop_defrect widthxheight %d x %d\n",
3033 cam->crop_defrect.width, cam->crop_defrect.height);
3034 pr_debug("End of %s: crop_current widthxheight %d x %d\n",
3036 cam->crop_current.width, cam->crop_current.height);
3042 * Disconnects the camera driver.
3044 static void mxc_v4l2_master_detach(struct v4l2_int_device *slave)
3047 cam_data *cam = slave->u.slave->master->priv;
3049 pr_debug("In MVC:mxc_v4l2_master_detach\n");
3051 if (cam->sensor_index > 1) {
3052 for (i = 0; i < cam->sensor_index; i++) {
3053 if (cam->all_sensors[i] != slave)
3055 /* Move all the sensors behind this
3056 * sensor one step forward
3058 for (; i < cam->sensor_index - 1; i++)
3059 cam->all_sensors[i] = cam->all_sensors[i+1];
3062 /* Point current sensor to the last one */
3063 cam->sensor = cam->all_sensors[cam->sensor_index - 2];
3067 cam->sensor_index--;
3068 vidioc_int_dev_exit(slave);
3072 * Entry point for the V4L2
3074 * @return Error code indicating success or failure
3076 static __init int camera_init(void)
3080 pr_debug("In MVC:camera_init\n");
3082 /* Register the device driver structure. */
3083 err = platform_driver_register(&mxc_v4l2_driver);
3085 pr_err("ERROR: v4l2 capture:camera_init: "
3086 "platform_driver_register failed.\n");
3094 * Exit and cleanup for the V4L2
3096 static void __exit camera_exit(void)
3098 pr_debug("In MVC: camera_exit\n");
3100 platform_driver_unregister(&mxc_v4l2_driver);
3103 module_init(camera_init);
3104 module_exit(camera_exit);
3106 module_param(video_nr, int, 0444);
3107 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
3108 MODULE_DESCRIPTION("V4L2 capture driver for Mxc based cameras");
3109 MODULE_LICENSE("GPL");
3110 MODULE_SUPPORTED_DEVICE("video");