aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobby Cai <r63905@freescale.com>2014-06-25 23:40:15 -0400
committerRobby Cai <r63905@freescale.com>2014-06-28 19:45:27 -0400
commit7550e961e94cc862bef951213d6835dce72a1e3e (patch)
tree48b04dd44ac22ae1f4b93c5c473eaa94fdcaf3bd
parentc66de709c8fc46d0d1e946c361cf4c25cda0c295 (diff)
ENGR00320056-1 v4l2 capture: imx6sx: Add dual camera support
on imx6sx, there are two CSI ports which supports dual camera. The patch changes the framework for this support, including: - introduce a new struct csi_soc for multiple instances. - add csi_read and csi_write API with data type 'struct csi_soc *' to differentiate register access for each CSI. - add a new parameter 'cam_data *' for the csi_* API (except csi_dmareq_rff_enable/disable) for dual instances. - move 'input_fmt' and 'bswapenable' to struct _cam_data. - initialize cam->bswapenable' to false. - allocate dynamically memory for struce v4l2_int_device thus to differentiate each CSI port. Signed-off-by: Robby Cai <r63905@freescale.com> (cherry picked from commit 997d1e896eae21fb4c78495df1e01a126913cb53)
-rw-r--r--drivers/media/platform/mxc/capture/csi_v4l2_capture.c215
-rw-r--r--drivers/media/platform/mxc/capture/fsl_csi.c173
-rw-r--r--drivers/media/platform/mxc/capture/fsl_csi.h85
-rw-r--r--drivers/media/platform/mxc/capture/mxc_v4l2_capture.h5
4 files changed, 276 insertions, 202 deletions
diff --git a/drivers/media/platform/mxc/capture/csi_v4l2_capture.c b/drivers/media/platform/mxc/capture/csi_v4l2_capture.c
index 3da162860205..3f759b635f8b 100644
--- a/drivers/media/platform/mxc/capture/csi_v4l2_capture.c
+++ b/drivers/media/platform/mxc/capture/csi_v4l2_capture.c
@@ -48,8 +48,6 @@ static int req_buf_number;
48static int csi_v4l2_master_attach(struct v4l2_int_device *slave); 48static int csi_v4l2_master_attach(struct v4l2_int_device *slave);
49static void csi_v4l2_master_detach(struct v4l2_int_device *slave); 49static void csi_v4l2_master_detach(struct v4l2_int_device *slave);
50static u8 camera_power(cam_data *cam, bool cameraOn); 50static u8 camera_power(cam_data *cam, bool cameraOn);
51static struct v4l2_format cam_input_fmt;
52static bool bswapenable;
53 51
54/*! Information about this driver. */ 52/*! Information about this driver. */
55static struct v4l2_int_master csi_v4l2_master = { 53static struct v4l2_int_master csi_v4l2_master = {
@@ -57,15 +55,6 @@ static struct v4l2_int_master csi_v4l2_master = {
57 .detach = csi_v4l2_master_detach, 55 .detach = csi_v4l2_master_detach,
58}; 56};
59 57
60static struct v4l2_int_device csi_v4l2_int_device = {
61 .module = THIS_MODULE,
62 .name = "csi_v4l2_cap",
63 .type = v4l2_int_type_master,
64 .u = {
65 .master = &csi_v4l2_master,
66 },
67};
68
69static struct v4l2_queryctrl pxp_controls[] = { 58static struct v4l2_queryctrl pxp_controls[] = {
70 { 59 {
71 .id = V4L2_CID_HFLIP, 60 .id = V4L2_CID_HFLIP,
@@ -307,11 +296,12 @@ static int pxp_process_update(cam_data *cam)
307 /* 296 /*
308 * Configure PxP for processing of new v4l2 buf 297 * Configure PxP for processing of new v4l2 buf
309 */ 298 */
310 pxp_conf->s0_param.pixel_fmt = v4l2_fmt_2_pxp_fmt(cam_input_fmt.fmt.pix.pixelformat); 299 pxp_conf->s0_param.pixel_fmt =
300 v4l2_fmt_2_pxp_fmt(cam->input_fmt.fmt.pix.pixelformat);
311 pxp_conf->s0_param.color_key = -1; 301 pxp_conf->s0_param.color_key = -1;
312 pxp_conf->s0_param.color_key_enable = false; 302 pxp_conf->s0_param.color_key_enable = false;
313 pxp_conf->s0_param.width = cam_input_fmt.fmt.pix.width; 303 pxp_conf->s0_param.width = cam->input_fmt.fmt.pix.width;
314 pxp_conf->s0_param.height = cam_input_fmt.fmt.pix.height; 304 pxp_conf->s0_param.height = cam->input_fmt.fmt.pix.height;
315 305
316 pxp_conf->ol_param[0].combine_enable = false; 306 pxp_conf->ol_param[0].combine_enable = false;
317 307
@@ -462,12 +452,12 @@ next:
462 list_del(cam->ready_q.next); 452 list_del(cam->ready_q.next);
463 list_add_tail(&ready_frame->queue, &cam->working_q); 453 list_add_tail(&ready_frame->queue, &cam->working_q);
464 454
465 __raw_writel(ready_frame->paddress, 455 csi_write(cam->csi_soc, ready_frame->paddress,
466 cam->ping_pong_csi == 1 ? CSI_CSIDMASA_FB1 : 456 cam->ping_pong_csi == 1 ? CSI_CSIDMASA_FB1 :
467 CSI_CSIDMASA_FB2); 457 CSI_CSIDMASA_FB2);
468 ready_frame->csi_buf_num = cam->ping_pong_csi; 458 ready_frame->csi_buf_num = cam->ping_pong_csi;
469 } else { 459 } else {
470 __raw_writel(cam->dummy_frame.paddress, 460 csi_write(cam->csi_soc, cam->dummy_frame.paddress,
471 cam->ping_pong_csi == 1 ? CSI_CSIDMASA_FB1 : 461 cam->ping_pong_csi == 1 ? CSI_CSIDMASA_FB1 :
472 CSI_CSIDMASA_FB2); 462 CSI_CSIDMASA_FB2);
473 } 463 }
@@ -488,10 +478,10 @@ static int csi_cap_image(cam_data *cam)
488{ 478{
489 unsigned int value; 479 unsigned int value;
490 480
491 value = __raw_readl(CSI_CSICR3); 481 value = csi_read(cam->csi_soc, CSI_CSICR3);
492 __raw_writel(value | BIT_FRMCNT_RST, CSI_CSICR3); 482 csi_write(cam->csi_soc, value | BIT_FRMCNT_RST, CSI_CSICR3);
493 value = __raw_readl(CSI_CSISR); 483 value = csi_read(cam->csi_soc, CSI_CSISR);
494 __raw_writel(value, CSI_CSISR); 484 csi_write(cam->csi_soc, value, CSI_CSISR);
495 485
496 return 0; 486 return 0;
497} 487}
@@ -711,7 +701,7 @@ static int csi_streamon(cam_data *cam)
711 frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue); 701 frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
712 list_del(cam->ready_q.next); 702 list_del(cam->ready_q.next);
713 list_add_tail(&frame->queue, &cam->working_q); 703 list_add_tail(&frame->queue, &cam->working_q);
714 __raw_writel(frame->paddress, CSI_CSIDMASA_FB1); 704 csi_write(cam->csi_soc, frame->paddress, CSI_CSIDMASA_FB1);
715 frame->csi_buf_num = 1; 705 frame->csi_buf_num = 1;
716 706
717 if (list_empty(&cam->ready_q)) { 707 if (list_empty(&cam->ready_q)) {
@@ -723,7 +713,7 @@ static int csi_streamon(cam_data *cam)
723 frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue); 713 frame = list_entry(cam->ready_q.next, struct mxc_v4l_frame, queue);
724 list_del(cam->ready_q.next); 714 list_del(cam->ready_q.next);
725 list_add_tail(&frame->queue, &cam->working_q); 715 list_add_tail(&frame->queue, &cam->working_q);
726 __raw_writel(frame->paddress, CSI_CSIDMASA_FB2); 716 csi_write(cam->csi_soc, frame->paddress, CSI_CSIDMASA_FB2);
727 frame->csi_buf_num = 2; 717 frame->csi_buf_num = 2;
728 spin_unlock_irqrestore(&cam->queue_int_lock, flags); 718 spin_unlock_irqrestore(&cam->queue_int_lock, flags);
729 719
@@ -733,12 +723,13 @@ static int csi_streamon(cam_data *cam)
733 723
734 local_irq_save(flags); 724 local_irq_save(flags);
735 for (timeout = 1000000; timeout > 0; timeout--) { 725 for (timeout = 1000000; timeout > 0; timeout--) {
736 if (__raw_readl(CSI_CSISR) & BIT_SOF_INT) { 726 if (csi_read(cam->csi_soc, CSI_CSISR) & BIT_SOF_INT) {
737 val = __raw_readl(CSI_CSICR3); 727 val = csi_read(cam->csi_soc, CSI_CSICR3);
738 __raw_writel(val | BIT_DMA_REFLASH_RFF, CSI_CSICR3); 728 csi_write(cam->csi_soc, val | BIT_DMA_REFLASH_RFF,
729 CSI_CSICR3);
739 /* Wait DMA reflash done */ 730 /* Wait DMA reflash done */
740 for (timeout2 = 1000000; timeout2 > 0; timeout2--) { 731 for (timeout2 = 1000000; timeout2 > 0; timeout2--) {
741 if (__raw_readl(CSI_CSICR3) & 732 if (csi_read(cam->csi_soc, CSI_CSICR3) &
742 BIT_DMA_REFLASH_RFF) 733 BIT_DMA_REFLASH_RFF)
743 cpu_relax(); 734 cpu_relax();
744 else 735 else
@@ -750,9 +741,9 @@ static int csi_streamon(cam_data *cam)
750 return -ETIME; 741 return -ETIME;
751 } 742 }
752 743
753 csi_dmareq_rff_enable(); 744 csi_dmareq_rff_enable(cam->csi_soc);
754 csi_enable_int(1); 745 csi_enable_int(cam, 1);
755 csi_enable(1); 746 csi_enable(cam, 1);
756 break; 747 break;
757 } else 748 } else
758 cpu_relax(); 749 cpu_relax();
@@ -781,21 +772,21 @@ static int csi_streamoff(cam_data *cam)
781 if (cam->capture_on == false) 772 if (cam->capture_on == false)
782 return 0; 773 return 0;
783 774
784 csi_dmareq_rff_disable(); 775 csi_dmareq_rff_disable(cam->csi_soc);
785 csi_disable_int(); 776 csi_disable_int(cam);
786 cam->capture_on = false; 777 cam->capture_on = false;
787 778
788 /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */ 779 /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
789 __raw_writel(0, CSI_CSIDMASA_FB1); 780 csi_write(cam->csi_soc, 0, CSI_CSIDMASA_FB1);
790 __raw_writel(0, CSI_CSIDMASA_FB2); 781 csi_write(cam->csi_soc, 0, CSI_CSIDMASA_FB2);
791 782
792 if (strcmp(csi_capture_inputs[cam->current_input].name, 783 if (strcmp(csi_capture_inputs[cam->current_input].name,
793 "Vadc") == 0) { 784 "Vadc") == 0) {
794 csi_buf_stride_set(0); 785 csi_buf_stride_set(cam, 0);
795 csi_deinterlace_enable(false); 786 csi_deinterlace_enable(cam, false);
796 csi_tvdec_enable(false); 787 csi_tvdec_enable(cam, false);
797 } 788 }
798 csi_enable(0); 789 csi_enable(cam, 0);
799 790
800 csi_free_frames(cam); 791 csi_free_frames(cam);
801 csi_free_frame_buf(cam); 792 csi_free_frame_buf(cam);
@@ -814,11 +805,13 @@ static int start_preview(cam_data *cam)
814{ 805{
815 unsigned long fb_addr = (unsigned long)cam->v4l2_fb.base; 806 unsigned long fb_addr = (unsigned long)cam->v4l2_fb.base;
816 807
817 __raw_writel(fb_addr, CSI_CSIDMASA_FB1); 808 csi_write(cam->csi_soc, fb_addr, CSI_CSIDMASA_FB1);
818 __raw_writel(fb_addr, CSI_CSIDMASA_FB2); 809 csi_write(cam->csi_soc, fb_addr, CSI_CSIDMASA_FB2);
819 __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF, CSI_CSICR3); 810 csi_write(cam->csi_soc,
811 csi_read(cam->csi_soc, CSI_CSICR3) | BIT_DMA_REFLASH_RFF,
812 CSI_CSICR3);
820 813
821 csi_enable_int(0); 814 csi_enable_int(cam, 0);
822 815
823 return 0; 816 return 0;
824} 817}
@@ -832,12 +825,14 @@ static int start_preview(cam_data *cam)
832 */ 825 */
833static int stop_preview(cam_data *cam) 826static int stop_preview(cam_data *cam)
834{ 827{
835 csi_disable_int(); 828 csi_disable_int(cam);
836 829
837 /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */ 830 /* set CSI_CSIDMASA_FB1 and CSI_CSIDMASA_FB2 to default value */
838 __raw_writel(0, CSI_CSIDMASA_FB1); 831 csi_write(cam->csi_soc, 0, CSI_CSIDMASA_FB1);
839 __raw_writel(0, CSI_CSIDMASA_FB2); 832 csi_write(cam->csi_soc, 0, CSI_CSIDMASA_FB2);
840 __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF, CSI_CSICR3); 833 csi_write(cam->csi_soc,
834 csi_read(cam->csi_soc, CSI_CSICR3) | BIT_DMA_REFLASH_RFF,
835 CSI_CSICR3);
841 836
842 return 0; 837 return 0;
843} 838}
@@ -948,7 +943,8 @@ static int csi_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
948 } 943 }
949 944
950 /* disable swap function */ 945 /* disable swap function */
951 csi_format_swap16(false); 946 csi_format_swap16(cam, false);
947 cam->bswapenable = false;
952 948
953 switch (f->fmt.pix.pixelformat) { 949 switch (f->fmt.pix.pixelformat) {
954 case V4L2_PIX_FMT_RGB565: 950 case V4L2_PIX_FMT_RGB565:
@@ -962,17 +958,17 @@ static int csi_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
962 case V4L2_PIX_FMT_UYVY: 958 case V4L2_PIX_FMT_UYVY:
963 size = f->fmt.pix.width * f->fmt.pix.height * 2; 959 size = f->fmt.pix.width * f->fmt.pix.height * 2;
964 bytesperline = f->fmt.pix.width * 2; 960 bytesperline = f->fmt.pix.width * 2;
965 if (cam_input_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) { 961 if (cam->input_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
966 csi_format_swap16(true); 962 csi_format_swap16(cam, true);
967 bswapenable = true; 963 cam->bswapenable = true;
968 } 964 }
969 break; 965 break;
970 case V4L2_PIX_FMT_YUYV: 966 case V4L2_PIX_FMT_YUYV:
971 size = f->fmt.pix.width * f->fmt.pix.height * 2; 967 size = f->fmt.pix.width * f->fmt.pix.height * 2;
972 bytesperline = f->fmt.pix.width * 2; 968 bytesperline = f->fmt.pix.width * 2;
973 if (cam_input_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) { 969 if (cam->input_fmt.fmt.pix.pixelformat == V4L2_PIX_FMT_UYVY) {
974 csi_format_swap16(true); 970 csi_format_swap16(cam, true);
975 bswapenable = true; 971 cam->bswapenable = true;
976 } 972 }
977 break; 973 break;
978 case V4L2_PIX_FMT_YUV420: 974 case V4L2_PIX_FMT_YUV420:
@@ -1000,8 +996,8 @@ static int csi_v4l2_s_fmt(cam_data *cam, struct v4l2_format *f)
1000 else 996 else
1001 size = f->fmt.pix.sizeimage; 997 size = f->fmt.pix.sizeimage;
1002 998
1003 if (cam_input_fmt.fmt.pix.sizeimage > f->fmt.pix.sizeimage) 999 if (cam->input_fmt.fmt.pix.sizeimage > f->fmt.pix.sizeimage)
1004 f->fmt.pix.sizeimage = cam_input_fmt.fmt.pix.sizeimage; 1000 f->fmt.pix.sizeimage = cam->input_fmt.fmt.pix.sizeimage;
1005 1001
1006 cam->v2f.fmt.pix = f->fmt.pix; 1002 cam->v2f.fmt.pix = f->fmt.pix;
1007 1003
@@ -1084,32 +1080,36 @@ static int csi_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
1084 } 1080 }
1085 1081
1086 vidioc_int_g_ifparm(cam->sensor, &ifparm); 1082 vidioc_int_g_ifparm(cam->sensor, &ifparm);
1087 cam_input_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1083 cam->input_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1088 vidioc_int_g_fmt_cap(cam->sensor, &cam_input_fmt); 1084 vidioc_int_g_fmt_cap(cam->sensor, &cam->input_fmt);
1089 1085
1090 pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n", 1086 pr_debug(" g_fmt_cap returns widthxheight of input as %d x %d\n",
1091 cam_input_fmt.fmt.pix.width, cam_input_fmt.fmt.pix.height); 1087 cam->input_fmt.fmt.pix.width, cam->input_fmt.fmt.pix.height);
1092 1088
1093 f = &cam_input_fmt; 1089 f = &cam->input_fmt;
1094 switch (f->fmt.pix.pixelformat) { 1090 switch (f->fmt.pix.pixelformat) {
1095 case V4L2_PIX_FMT_YUV444: 1091 case V4L2_PIX_FMT_YUV444:
1096 size = f->fmt.pix.width * f->fmt.pix.height * 4; 1092 size = f->fmt.pix.width * f->fmt.pix.height * 4;
1097 csi_set_32bit_imagpara(f->fmt.pix.width, 1093 csi_set_32bit_imagpara(cam,
1094 f->fmt.pix.width,
1098 f->fmt.pix.height); 1095 f->fmt.pix.height);
1099 break; 1096 break;
1100 case V4L2_PIX_FMT_UYVY: 1097 case V4L2_PIX_FMT_UYVY:
1101 size = f->fmt.pix.width * f->fmt.pix.height * 2; 1098 size = f->fmt.pix.width * f->fmt.pix.height * 2;
1102 csi_set_16bit_imagpara(f->fmt.pix.width, 1099 csi_set_16bit_imagpara(cam,
1100 f->fmt.pix.width,
1103 f->fmt.pix.height); 1101 f->fmt.pix.height);
1104 break; 1102 break;
1105 case V4L2_PIX_FMT_YUYV: 1103 case V4L2_PIX_FMT_YUYV:
1106 size = f->fmt.pix.width * f->fmt.pix.height * 2; 1104 size = f->fmt.pix.width * f->fmt.pix.height * 2;
1107 csi_set_16bit_imagpara(f->fmt.pix.width, 1105 csi_set_16bit_imagpara(cam,
1106 f->fmt.pix.width,
1108 f->fmt.pix.height); 1107 f->fmt.pix.height);
1109 break; 1108 break;
1110 case V4L2_PIX_FMT_YUV420: 1109 case V4L2_PIX_FMT_YUV420:
1111 size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2; 1110 size = f->fmt.pix.width * f->fmt.pix.height * 3 / 2;
1112 csi_set_12bit_imagpara(f->fmt.pix.width, 1111 csi_set_12bit_imagpara(cam,
1112 f->fmt.pix.width,
1113 f->fmt.pix.height); 1113 f->fmt.pix.height);
1114 break; 1114 break;
1115 case V4L2_PIX_FMT_YUV422P: 1115 case V4L2_PIX_FMT_YUV422P:
@@ -1125,8 +1125,8 @@ static int csi_v4l2_s_param(cam_data *cam, struct v4l2_streamparm *parm)
1125 f->fmt.pix.sizeimage = size; 1125 f->fmt.pix.sizeimage = size;
1126 1126
1127 cam->crop_bounds.top = cam->crop_bounds.left = 0; 1127 cam->crop_bounds.top = cam->crop_bounds.left = 0;
1128 cam->crop_bounds.width = cam_input_fmt.fmt.pix.width; 1128 cam->crop_bounds.width = cam->input_fmt.fmt.pix.width;
1129 cam->crop_bounds.height = cam_input_fmt.fmt.pix.height; 1129 cam->crop_bounds.height = cam->input_fmt.fmt.pix.height;
1130 cam->crop_current.width = cam->crop_bounds.width; 1130 cam->crop_current.width = cam->crop_bounds.width;
1131 cam->crop_current.height = cam->crop_bounds.height; 1131 cam->crop_current.height = cam->crop_bounds.height;
1132 1132
@@ -1201,9 +1201,9 @@ static int csi_v4l_s_std(cam_data *cam, v4l2_std_id e)
1201 strcpy(cam->standard.name, video_fmts[video_index].name); 1201 strcpy(cam->standard.name, video_fmts[video_index].name);
1202 1202
1203 /* Enable csi PAL/NTSC deinterlace mode */ 1203 /* Enable csi PAL/NTSC deinterlace mode */
1204 csi_buf_stride_set(video_fmts[video_index].active_width); 1204 csi_buf_stride_set(cam, video_fmts[video_index].active_width);
1205 csi_deinterlace_mode(cam->standard.id); 1205 csi_deinterlace_mode(cam, cam->standard.id);
1206 csi_deinterlace_enable(true); 1206 csi_deinterlace_enable(cam, true);
1207 1207
1208 /* crop will overwrite */ 1208 /* crop will overwrite */
1209 cam->crop_bounds.width = video_fmts[video_index].active_width; 1209 cam->crop_bounds.width = video_fmts[video_index].active_width;
@@ -1231,7 +1231,7 @@ static int csi_v4l_g_std(cam_data *cam, v4l2_std_id *e)
1231{ 1231{
1232 struct v4l2_format tv_fmt; 1232 struct v4l2_format tv_fmt;
1233 1233
1234 pr_debug("In csi_v4l2_g_std\n"); 1234 pr_debug("In csi_v4l2_g_std, cam->csi %d\n", cam->csi);
1235 1235
1236 if (cam->device_type == 1) { 1236 if (cam->device_type == 1) {
1237 /* Use this function to get what the TV-In device detects the 1237 /* Use this function to get what the TV-In device detects the
@@ -1256,13 +1256,13 @@ static int csi_v4l_g_std(cam_data *cam, v4l2_std_id *e)
1256 return 0; 1256 return 0;
1257} 1257}
1258 1258
1259static void csi_input_select(int input_select) 1259static void csi_input_select(cam_data *cam)
1260{ 1260{
1261 if (strcmp(csi_capture_inputs[input_select].name, "Vadc") == 0) 1261 if (strcmp(csi_capture_inputs[cam->current_input].name, "Vadc") == 0)
1262 /* Enable csi tvdec */ 1262 /* Enable csi tvdec */
1263 csi_tvdec_enable(true); 1263 csi_tvdec_enable(cam, true);
1264 else 1264 else
1265 csi_tvdec_enable(false); 1265 csi_tvdec_enable(cam, false);
1266} 1266}
1267 1267
1268/*! 1268/*!
@@ -1332,8 +1332,8 @@ static int csi_v4l_dqueue(cam_data *cam, struct v4l2_buffer *buf)
1332 * If want to do preview on LCD, use PxP CSC to convert from UYVY 1332 * If want to do preview on LCD, use PxP CSC to convert from UYVY
1333 * to RGB565; but for encoding, usually we don't use RGB format. 1333 * to RGB565; but for encoding, usually we don't use RGB format.
1334 */ 1334 */
1335 if (cam->v2f.fmt.pix.pixelformat != cam_input_fmt.fmt.pix.pixelformat 1335 if (cam->v2f.fmt.pix.pixelformat != cam->input_fmt.fmt.pix.pixelformat
1336 && !bswapenable) { 1336 && !cam->bswapenable) {
1337 sg_dma_address(&cam->sg[0]) = buf->m.offset; 1337 sg_dma_address(&cam->sg[0]) = buf->m.offset;
1338 /* last frame buffer as pxp output buffer */ 1338 /* last frame buffer as pxp output buffer */
1339 sg_dma_address(&cam->sg[1]) = 1339 sg_dma_address(&cam->sg[1]) =
@@ -1467,7 +1467,6 @@ static int csi_v4l_close(struct file *file)
1467 file->private_data = NULL; 1467 file->private_data = NULL;
1468 vidioc_int_s_power(cam->sensor, 0); 1468 vidioc_int_s_power(cam->sensor, 0);
1469 clk_disable_unprepare(sensor->sensor_clk); 1469 clk_disable_unprepare(sensor->sensor_clk);
1470 csi_clk_disable();
1471 } 1470 }
1472 1471
1473 return err; 1472 return err;
@@ -1510,19 +1509,23 @@ static ssize_t csi_v4l_read(struct file *file, char *buf, size_t count,
1510 return -ENOMEM; 1509 return -ENOMEM;
1511 } 1510 }
1512 cam->still_counter = 0; 1511 cam->still_counter = 0;
1513 __raw_writel(cam->still_buf[0], CSI_CSIDMASA_FB2); 1512 csi_write(cam->csi_soc, cam->still_buf[0], CSI_CSIDMASA_FB2);
1514 __raw_writel(cam->still_buf[0], CSI_CSIDMASA_FB1); 1513 csi_write(cam->csi_soc, cam->still_buf[0], CSI_CSIDMASA_FB1);
1515 __raw_writel(__raw_readl(CSI_CSICR3) | BIT_DMA_REFLASH_RFF, 1514 csi_write(cam->csi_soc,
1516 CSI_CSICR3); 1515 csi_read(cam->csi_soc, CSI_CSICR3) |
1517 __raw_writel(__raw_readl(CSI_CSISR), CSI_CSISR); 1516 BIT_DMA_REFLASH_RFF,
1518 __raw_writel(__raw_readl(CSI_CSICR3) | BIT_FRMCNT_RST, 1517 CSI_CSICR3);
1519 CSI_CSICR3); 1518 csi_write(cam->csi_soc, csi_read(cam->csi_soc, CSI_CSISR),
1520 csi_enable_int(1); 1519 CSI_CSISR);
1521 csi_enable(1); 1520 csi_write(cam->csi_soc,
1521 csi_read(cam->csi_soc, CSI_CSICR3) | BIT_FRMCNT_RST,
1522 CSI_CSICR3);
1523 csi_enable_int(cam, 1);
1524 csi_enable(cam, 1);
1522 } 1525 }
1523 1526
1524 wait_event_interruptible(cam->still_queue, cam->still_counter); 1527 wait_event_interruptible(cam->still_queue, cam->still_counter);
1525 csi_disable_int(); 1528 csi_disable_int(cam);
1526 err = copy_to_user(buf, cam->still_buf_vaddr, 1529 err = copy_to_user(buf, cam->still_buf_vaddr,
1527 cam->v2f.fmt.pix.sizeimage); 1530 cam->v2f.fmt.pix.sizeimage);
1528 1531
@@ -1965,7 +1968,7 @@ static long csi_v4l_do_ioctl(struct file *file,
1965 1968
1966 cam->current_input = *index; 1969 cam->current_input = *index;
1967 1970
1968 csi_input_select(cam->current_input); 1971 csi_input_select(cam);
1969 break; 1972 break;
1970 } 1973 }
1971 case VIDIOC_G_OUTPUT: 1974 case VIDIOC_G_OUTPUT:
@@ -2066,11 +2069,20 @@ static struct video_device csi_v4l_template = {
2066 * 2069 *
2067 * @return status 0 Success 2070 * @return status 0 Success
2068 */ 2071 */
2069static void init_camera_struct(cam_data *cam) 2072static void init_camera_struct(cam_data *cam, struct platform_device *pdev)
2070{ 2073{
2071 struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data; 2074 struct pxp_proc_data *proc_data = &cam->pxp_conf.proc_data;
2075 struct device_node *np = pdev->dev.of_node;
2076 int ret = 0;
2077 int csi_id;
2072 pr_debug("In MVC: %s\n", __func__); 2078 pr_debug("In MVC: %s\n", __func__);
2073 2079
2080 ret = of_property_read_u32(np, "csi_id", &csi_id);
2081 if (ret) {
2082 dev_err(&pdev->dev, "csi_id missing or invalid\n");
2083 return;
2084 }
2085
2074 proc_data->hflip = 0; 2086 proc_data->hflip = 0;
2075 proc_data->vflip = 0; 2087 proc_data->vflip = 0;
2076 proc_data->rotate = 0; 2088 proc_data->rotate = 0;
@@ -2082,6 +2094,9 @@ static void init_camera_struct(cam_data *cam)
2082 sema_init(&cam->param_lock, 1); 2094 sema_init(&cam->param_lock, 1);
2083 sema_init(&cam->busy_lock, 1); 2095 sema_init(&cam->busy_lock, 1);
2084 2096
2097 /* TODO sanity check */
2098 cam->csi_soc = csi_get_soc(csi_id);
2099
2085 cam->video_dev = video_device_alloc(); 2100 cam->video_dev = video_device_alloc();
2086 if (cam->video_dev == NULL) 2101 if (cam->video_dev == NULL)
2087 return; 2102 return;
@@ -2126,11 +2141,18 @@ static void init_camera_struct(cam_data *cam)
2126 cam->crop_bounds.height = 480; 2141 cam->crop_bounds.height = 480;
2127 cam->crop_current = cam->crop_defrect = cam->crop_bounds; 2142 cam->crop_current = cam->crop_defrect = cam->crop_bounds;
2128 2143
2144 cam->csi = csi_id;
2129 cam->enc_callback = camera_callback; 2145 cam->enc_callback = camera_callback;
2130 csi_start_callback(cam); 2146 csi_start_callback(cam);
2131 init_waitqueue_head(&cam->power_queue); 2147 init_waitqueue_head(&cam->power_queue);
2132 spin_lock_init(&cam->queue_int_lock); 2148 spin_lock_init(&cam->queue_int_lock);
2133 spin_lock_init(&cam->dqueue_int_lock); 2149 spin_lock_init(&cam->dqueue_int_lock);
2150
2151 cam->self = kmalloc(sizeof(struct v4l2_int_device), GFP_KERNEL);
2152 cam->self->module = THIS_MODULE;
2153 sprintf(cam->self->name, "csi_v4l2_cap%d", cam->csi);
2154 cam->self->type = v4l2_int_type_master;
2155 cam->self->u.master = &csi_v4l2_master;
2134} 2156}
2135 2157
2136/*! 2158/*!
@@ -2172,14 +2194,13 @@ static int csi_v4l2_probe(struct platform_device *pdev)
2172 err = -ENOMEM; 2194 err = -ENOMEM;
2173 goto out; 2195 goto out;
2174 } 2196 }
2175 memset(&cam_input_fmt, 0, sizeof(cam_input_fmt)); 2197 memset(&g_cam->input_fmt, 0, sizeof(g_cam->input_fmt));
2176 init_camera_struct(g_cam); 2198 init_camera_struct(g_cam, pdev);
2177 platform_set_drvdata(pdev, (void *)g_cam); 2199 platform_set_drvdata(pdev, (void *)g_cam);
2178 2200
2179 /* Set up the v4l2 device and register it */ 2201 /* Set up the v4l2 device and register it */
2180 csi_v4l2_int_device.priv = g_cam; 2202 g_cam->self->priv = g_cam;
2181 /* This function contains a bug that won't let this be rmmod'd. */ 2203 v4l2_int_device_register(g_cam->self);
2182 v4l2_int_device_register(&csi_v4l2_int_device);
2183 2204
2184 /* register v4l video device */ 2205 /* register v4l video device */
2185 if (video_register_device(g_cam->video_dev, VFL_TYPE_GRABBER, video_nr) 2206 if (video_register_device(g_cam->video_dev, VFL_TYPE_GRABBER, video_nr)
@@ -2209,7 +2230,7 @@ static int csi_v4l2_remove(struct platform_device *pdev)
2209 "-- setting ops to NULL\n"); 2230 "-- setting ops to NULL\n");
2210 } else { 2231 } else {
2211 pr_info("V4L2 freeing image input device\n"); 2232 pr_info("V4L2 freeing image input device\n");
2212 v4l2_int_device_unregister(&csi_v4l2_int_device); 2233 v4l2_int_device_unregister(g_cam->self);
2213 csi_stop_callback(g_cam); 2234 csi_stop_callback(g_cam);
2214 video_unregister_device(g_cam->video_dev); 2235 video_unregister_device(g_cam->video_dev);
2215 platform_set_drvdata(pdev, NULL); 2236 platform_set_drvdata(pdev, NULL);
@@ -2304,17 +2325,23 @@ static struct platform_driver csi_v4l2_driver = {
2304static int csi_v4l2_master_attach(struct v4l2_int_device *slave) 2325static int csi_v4l2_master_attach(struct v4l2_int_device *slave)
2305{ 2326{
2306 cam_data *cam = slave->u.slave->master->priv; 2327 cam_data *cam = slave->u.slave->master->priv;
2328 struct sensor_data *sdata = slave->priv;
2307 struct v4l2_format cam_fmt; 2329 struct v4l2_format cam_fmt;
2308 2330
2309 pr_debug("In MVC: %s\n", __func__); 2331 pr_debug("In MVC: %s\n", __func__);
2310 pr_debug(" slave.name = %s\n", slave->name); 2332 pr_debug(" slave.name = %s\n", slave->name);
2311 pr_debug(" master.name = %s\n", slave->u.slave->master->name); 2333 pr_debug(" master.name = %s\n", slave->u.slave->master->name);
2312 2334
2313 cam->sensor = slave;
2314 if (slave == NULL) { 2335 if (slave == NULL) {
2315 pr_err("ERROR: v4l2 capture: slave parameter not valid.\n"); 2336 pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
2316 return -1; 2337 return -1;
2317 } 2338 }
2339 if (sdata->csi != cam->csi) {
2340 pr_debug("%s: csi doesn't match\n", __func__);
2341 return -1;
2342 }
2343
2344 cam->sensor = slave;
2318 2345
2319 cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 2346 cam_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2320 vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt); 2347 vidioc_int_g_fmt_cap(cam->sensor, &cam_fmt);
diff --git a/drivers/media/platform/mxc/capture/fsl_csi.c b/drivers/media/platform/mxc/capture/fsl_csi.c
index 2839e9fa0d8e..602899d70ce0 100644
--- a/drivers/media/platform/mxc/capture/fsl_csi.c
+++ b/drivers/media/platform/mxc/capture/fsl_csi.c
@@ -33,9 +33,9 @@
33#include "mxc_v4l2_capture.h" 33#include "mxc_v4l2_capture.h"
34#include "fsl_csi.h" 34#include "fsl_csi.h"
35 35
36void __iomem *csi_regbase; 36#define CSI_MAX_NUM 2
37EXPORT_SYMBOL(csi_regbase); 37struct csi_soc csi_array[CSI_MAX_NUM], *csi;
38static int irq_nr; 38
39static csi_irq_callback_t g_callback; 39static csi_irq_callback_t g_callback;
40static void *g_callback_data; 40static void *g_callback_data;
41static struct clk *disp_axi_clk; 41static struct clk *disp_axi_clk;
@@ -61,9 +61,10 @@ EXPORT_SYMBOL(csi_clk_disable);
61static irqreturn_t csi_irq_handler(int irq, void *data) 61static irqreturn_t csi_irq_handler(int irq, void *data)
62{ 62{
63 cam_data *cam = (cam_data *) data; 63 cam_data *cam = (cam_data *) data;
64 unsigned long status = __raw_readl(CSI_CSISR); 64 struct csi_soc *csi = &csi_array[cam->csi];
65 unsigned long status = __raw_readl(csi->regbase + CSI_CSISR);
65 66
66 __raw_writel(status, CSI_CSISR); 67 __raw_writel(status, csi->regbase + CSI_CSISR);
67 68
68 if (status & BIT_HRESP_ERR_INT) 69 if (status & BIT_HRESP_ERR_INT)
69 pr_warning("Hresponse error is detected.\n"); 70 pr_warning("Hresponse error is detected.\n");
@@ -100,24 +101,25 @@ static irqreturn_t csi_irq_handler(int irq, void *data)
100 return IRQ_HANDLED; 101 return IRQ_HANDLED;
101} 102}
102 103
103static void csihw_reset_frame_count(void) 104static void csihw_reset_frame_count(struct csi_soc *csi)
104{ 105{
105 __raw_writel(__raw_readl(CSI_CSICR3) | BIT_FRMCNT_RST, CSI_CSICR3); 106 __raw_writel(__raw_readl(csi->regbase + CSI_CSICR3) | BIT_FRMCNT_RST,
107 csi->regbase + CSI_CSICR3);
106} 108}
107 109
108static void csihw_reset(void) 110static void csihw_reset(struct csi_soc *csi)
109{ 111{
110 csihw_reset_frame_count(); 112 csihw_reset_frame_count(csi);
111 __raw_writel(CSICR1_RESET_VAL, CSI_CSICR1); 113 __raw_writel(CSICR1_RESET_VAL, csi->regbase + CSI_CSICR1);
112 __raw_writel(CSICR2_RESET_VAL, CSI_CSICR2); 114 __raw_writel(CSICR2_RESET_VAL, csi->regbase + CSI_CSICR2);
113 __raw_writel(CSICR3_RESET_VAL, CSI_CSICR3); 115 __raw_writel(CSICR3_RESET_VAL, csi->regbase + CSI_CSICR3);
114} 116}
115 117
116/*! 118/*!
117 * csi_init_interface 119 * csi_init_interface
118 * Init csi interface 120 * Init csi interface
119 */ 121 */
120void csi_init_interface(void) 122static void csi_init_interface(struct csi_soc *csi)
121{ 123{
122 unsigned int val = 0; 124 unsigned int val = 0;
123 unsigned int imag_para; 125 unsigned int imag_para;
@@ -129,22 +131,22 @@ void csi_init_interface(void)
129 val |= BIT_FCC; 131 val |= BIT_FCC;
130 val |= 1 << SHIFT_MCLKDIV; 132 val |= 1 << SHIFT_MCLKDIV;
131 val |= BIT_MCLKEN; 133 val |= BIT_MCLKEN;
132 __raw_writel(val, CSI_CSICR1); 134 __raw_writel(val, csi->regbase + CSI_CSICR1);
133 135
134 imag_para = (640 << 16) | 960; 136 imag_para = (640 << 16) | 960;
135 __raw_writel(imag_para, CSI_CSIIMAG_PARA); 137 __raw_writel(imag_para, csi->regbase + CSI_CSIIMAG_PARA);
136 138
137 val = 0x1010; 139 val = 0x1010;
138 val |= BIT_DMA_REFLASH_RFF; 140 val |= BIT_DMA_REFLASH_RFF;
139 __raw_writel(val, CSI_CSICR3); 141 __raw_writel(val, csi->regbase + CSI_CSICR3);
140} 142}
141EXPORT_SYMBOL(csi_init_interface);
142 143
143void csi_format_swap16(bool enable) 144void csi_format_swap16(cam_data *cam, bool enable)
144{ 145{
146 struct csi_soc *csi = &csi_array[cam->csi];
145 unsigned int val; 147 unsigned int val;
146 148
147 val = __raw_readl(CSI_CSICR1); 149 val = __raw_readl(csi->regbase + CSI_CSICR1);
148 if (enable) { 150 if (enable) {
149 val |= BIT_PACK_DIR; 151 val |= BIT_PACK_DIR;
150 val |= BIT_SWAP16_EN; 152 val |= BIT_SWAP16_EN;
@@ -153,7 +155,7 @@ void csi_format_swap16(bool enable)
153 val &= ~BIT_SWAP16_EN; 155 val &= ~BIT_SWAP16_EN;
154 } 156 }
155 157
156 __raw_writel(val, CSI_CSICR1); 158 __raw_writel(val, csi->regbase + CSI_CSICR1);
157} 159}
158EXPORT_SYMBOL(csi_format_swap16); 160EXPORT_SYMBOL(csi_format_swap16);
159 161
@@ -172,7 +174,8 @@ void csi_start_callback(void *data)
172{ 174{
173 cam_data *cam = (cam_data *) data; 175 cam_data *cam = (cam_data *) data;
174 176
175 if (request_irq(irq_nr, csi_irq_handler, 0, "csi", cam) < 0) 177 if (request_irq(csi_array[cam->csi].irq_nr, csi_irq_handler, 0, "csi",
178 cam) < 0)
176 pr_debug("CSI error: irq request fail\n"); 179 pr_debug("CSI error: irq request fail\n");
177 180
178} 181}
@@ -182,13 +185,14 @@ void csi_stop_callback(void *data)
182{ 185{
183 cam_data *cam = (cam_data *) data; 186 cam_data *cam = (cam_data *) data;
184 187
185 free_irq(irq_nr, cam); 188 free_irq(csi_array[cam->csi].irq_nr, cam);
186} 189}
187EXPORT_SYMBOL(csi_stop_callback); 190EXPORT_SYMBOL(csi_stop_callback);
188 191
189void csi_enable_int(int arg) 192void csi_enable_int(cam_data *cam, int arg)
190{ 193{
191 unsigned long cr1 = __raw_readl(CSI_CSICR1); 194 struct csi_soc *csi = &csi_array[cam->csi];
195 unsigned long cr1 = __raw_readl(csi->regbase + CSI_CSICR1);
192 196
193 cr1 |= BIT_SOF_INTEN; 197 cr1 |= BIT_SOF_INTEN;
194 if (arg == 1) { 198 if (arg == 1) {
@@ -196,69 +200,76 @@ void csi_enable_int(int arg)
196 cr1 |= BIT_FB1_DMA_DONE_INTEN; 200 cr1 |= BIT_FB1_DMA_DONE_INTEN;
197 cr1 |= BIT_FB2_DMA_DONE_INTEN; 201 cr1 |= BIT_FB2_DMA_DONE_INTEN;
198 } 202 }
199 __raw_writel(cr1, CSI_CSICR1); 203 __raw_writel(cr1, csi->regbase + CSI_CSICR1);
200} 204}
201EXPORT_SYMBOL(csi_enable_int); 205EXPORT_SYMBOL(csi_enable_int);
202 206
203void csi_disable_int(void) 207void csi_disable_int(cam_data *cam)
204{ 208{
205 unsigned long cr1 = __raw_readl(CSI_CSICR1); 209 struct csi_soc *csi = &csi_array[cam->csi];
210 unsigned long cr1 = __raw_readl(csi->regbase + CSI_CSICR1);
206 211
207 cr1 &= ~BIT_SOF_INTEN; 212 cr1 &= ~BIT_SOF_INTEN;
208 cr1 &= ~BIT_FB1_DMA_DONE_INTEN; 213 cr1 &= ~BIT_FB1_DMA_DONE_INTEN;
209 cr1 &= ~BIT_FB2_DMA_DONE_INTEN; 214 cr1 &= ~BIT_FB2_DMA_DONE_INTEN;
210 __raw_writel(cr1, CSI_CSICR1); 215 __raw_writel(cr1, csi->regbase + CSI_CSICR1);
211} 216}
212EXPORT_SYMBOL(csi_disable_int); 217EXPORT_SYMBOL(csi_disable_int);
213 218
214void csi_enable(int arg) 219void csi_enable(cam_data *cam, int arg)
215{ 220{
216 unsigned long cr = __raw_readl(CSI_CSICR18); 221 struct csi_soc *csi = &csi_array[cam->csi];
222 unsigned long cr = __raw_readl(csi->regbase + CSI_CSICR18);
217 223
218 if (arg == 1) 224 if (arg == 1)
219 cr |= BIT_CSI_ENABLE; 225 cr |= BIT_CSI_ENABLE;
220 else 226 else
221 cr &= ~BIT_CSI_ENABLE; 227 cr &= ~BIT_CSI_ENABLE;
222 __raw_writel(cr, CSI_CSICR18); 228 __raw_writel(cr, csi->regbase + CSI_CSICR18);
223} 229}
224EXPORT_SYMBOL(csi_enable); 230EXPORT_SYMBOL(csi_enable);
225 231
226void csi_buf_stride_set(u32 stride) 232void csi_buf_stride_set(cam_data *cam, u32 stride)
227{ 233{
228 __raw_writel(stride, CSI_CSIFBUF_PARA); 234 struct csi_soc *csi = &csi_array[cam->csi];
235
236 __raw_writel(stride, csi->regbase + CSI_CSIFBUF_PARA);
229} 237}
230EXPORT_SYMBOL(csi_buf_stride_set); 238EXPORT_SYMBOL(csi_buf_stride_set);
231 239
232void csi_deinterlace_enable(bool enable) 240void csi_deinterlace_enable(cam_data *cam, bool enable)
233{ 241{
234 unsigned long cr18 = __raw_readl(CSI_CSICR18); 242 struct csi_soc *csi = &csi_array[cam->csi];
243 unsigned long cr18 = __raw_readl(csi->regbase + CSI_CSICR18);
235 244
236 if (enable == true) 245 if (enable == true)
237 cr18 |= BIT_DEINTERLACE_EN; 246 cr18 |= BIT_DEINTERLACE_EN;
238 else 247 else
239 cr18 &= ~BIT_DEINTERLACE_EN; 248 cr18 &= ~BIT_DEINTERLACE_EN;
240 249
241 __raw_writel(cr18, CSI_CSICR18); 250 __raw_writel(cr18, csi->regbase + CSI_CSICR18);
242} 251}
243EXPORT_SYMBOL(csi_deinterlace_enable); 252EXPORT_SYMBOL(csi_deinterlace_enable);
244 253
245void csi_deinterlace_mode(int mode) 254void csi_deinterlace_mode(cam_data *cam, int mode)
246{ 255{
247 unsigned long cr18 = __raw_readl(CSI_CSICR18); 256 struct csi_soc *csi = &csi_array[cam->csi];
257 unsigned long cr18 = __raw_readl(csi->regbase + CSI_CSICR18);
248 258
249 if (mode == V4L2_STD_NTSC) 259 if (mode == V4L2_STD_NTSC)
250 cr18 |= BIT_NTSC_EN; 260 cr18 |= BIT_NTSC_EN;
251 else 261 else
252 cr18 &= ~BIT_NTSC_EN; 262 cr18 &= ~BIT_NTSC_EN;
253 263
254 __raw_writel(cr18, CSI_CSICR18); 264 __raw_writel(cr18, csi->regbase + CSI_CSICR18);
255} 265}
256EXPORT_SYMBOL(csi_deinterlace_mode); 266EXPORT_SYMBOL(csi_deinterlace_mode);
257 267
258void csi_tvdec_enable(bool enable) 268void csi_tvdec_enable(cam_data *cam, bool enable)
259{ 269{
260 unsigned long cr18 = __raw_readl(CSI_CSICR18); 270 struct csi_soc *csi = &csi_array[cam->csi];
261 unsigned long cr1 = __raw_readl(CSI_CSICR1); 271 unsigned long cr18 = __raw_readl(csi->regbase + CSI_CSICR18);
272 unsigned long cr1 = __raw_readl(csi->regbase + CSI_CSICR1);
262 273
263 if (enable == true) { 274 if (enable == true) {
264 cr18 |= (BIT_TVDECODER_IN_EN | BIT_BASEADDR_SWITCH_EN); 275 cr18 |= (BIT_TVDECODER_IN_EN | BIT_BASEADDR_SWITCH_EN);
@@ -270,71 +281,85 @@ void csi_tvdec_enable(bool enable)
270 cr1 |= BIT_SOF_POL | BIT_REDGE; 281 cr1 |= BIT_SOF_POL | BIT_REDGE;
271 } 282 }
272 283
273 __raw_writel(cr18, CSI_CSICR18); 284 __raw_writel(cr18, csi->regbase + CSI_CSICR18);
274 __raw_writel(cr1, CSI_CSICR1); 285 __raw_writel(cr1, csi->regbase + CSI_CSICR1);
275} 286}
276EXPORT_SYMBOL(csi_tvdec_enable); 287EXPORT_SYMBOL(csi_tvdec_enable);
277 288
278void csi_set_32bit_imagpara(int width, int height) 289void csi_set_32bit_imagpara(cam_data *cam, int width, int height)
279{ 290{
291 struct csi_soc *csi = &csi_array[cam->csi];
280 int imag_para = 0; 292 int imag_para = 0;
281 unsigned long cr3 = __raw_readl(CSI_CSICR3); 293 unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3);
282 294
283 imag_para = (width << 16) | height; 295 imag_para = (width << 16) | height;
284 __raw_writel(imag_para, CSI_CSIIMAG_PARA); 296 __raw_writel(imag_para, csi->regbase + CSI_CSIIMAG_PARA);
285 297
286 298
287 /* reflash the embeded DMA controller */ 299 /* reflash the embeded DMA controller */
288 __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3); 300 __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, csi->regbase + CSI_CSICR3);
289} 301}
290EXPORT_SYMBOL(csi_set_32bit_imagpara); 302EXPORT_SYMBOL(csi_set_32bit_imagpara);
291 303
292void csi_set_16bit_imagpara(int width, int height) 304void csi_set_16bit_imagpara(cam_data *cam, int width, int height)
293{ 305{
306 struct csi_soc *csi = &csi_array[cam->csi];
294 int imag_para = 0; 307 int imag_para = 0;
295 unsigned long cr3 = __raw_readl(CSI_CSICR3); 308 unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3);
296 309
297 imag_para = (width << 16) | (height * 2); 310 imag_para = (width << 16) | (height * 2);
298 __raw_writel(imag_para, CSI_CSIIMAG_PARA); 311 __raw_writel(imag_para, csi->regbase + CSI_CSIIMAG_PARA);
299 312
300 /* reflash the embeded DMA controller */ 313 /* reflash the embeded DMA controller */
301 __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3); 314 __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, csi->regbase + CSI_CSICR3);
302} 315}
303EXPORT_SYMBOL(csi_set_16bit_imagpara); 316EXPORT_SYMBOL(csi_set_16bit_imagpara);
304 317
305void csi_set_12bit_imagpara(int width, int height) 318void csi_set_12bit_imagpara(cam_data *cam, int width, int height)
306{ 319{
320 struct csi_soc *csi = &csi_array[cam->csi];
307 int imag_para = 0; 321 int imag_para = 0;
308 unsigned long cr3 = __raw_readl(CSI_CSICR3); 322 unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3);
309 323
310 imag_para = (width << 16) | (height * 3 / 2); 324 imag_para = (width << 16) | (height * 3 / 2);
311 __raw_writel(imag_para, CSI_CSIIMAG_PARA); 325 __raw_writel(imag_para, csi->regbase + CSI_CSIIMAG_PARA);
312 326
313 /* reflash the embeded DMA controller */ 327 /* reflash the embeded DMA controller */
314 __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, CSI_CSICR3); 328 __raw_writel(cr3 | BIT_DMA_REFLASH_RFF, csi->regbase + CSI_CSICR3);
315} 329}
316EXPORT_SYMBOL(csi_set_12bit_imagpara); 330EXPORT_SYMBOL(csi_set_12bit_imagpara);
317 331
318void csi_dmareq_rff_enable(void) 332void csi_dmareq_rff_enable(struct csi_soc *csi)
319{ 333{
320 unsigned long cr3 = __raw_readl(CSI_CSICR3); 334 unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3);
321 335
322 cr3 |= BIT_DMA_REQ_EN_RFF; 336 cr3 |= BIT_DMA_REQ_EN_RFF;
323 cr3 |= BIT_HRESP_ERR_EN; 337 cr3 |= BIT_HRESP_ERR_EN;
324 __raw_writel(cr3, CSI_CSICR3); 338 __raw_writel(cr3, csi->regbase + CSI_CSICR3);
325} 339}
326EXPORT_SYMBOL(csi_dmareq_rff_enable); 340EXPORT_SYMBOL(csi_dmareq_rff_enable);
327 341
328void csi_dmareq_rff_disable(void) 342void csi_dmareq_rff_disable(struct csi_soc *csi)
329{ 343{
330 unsigned long cr3 = __raw_readl(CSI_CSICR3); 344 unsigned long cr3 = __raw_readl(csi->regbase + CSI_CSICR3);
331 345
332 cr3 &= ~BIT_DMA_REQ_EN_RFF; 346 cr3 &= ~BIT_DMA_REQ_EN_RFF;
333 cr3 &= ~BIT_HRESP_ERR_EN; 347 cr3 &= ~BIT_HRESP_ERR_EN;
334 __raw_writel(cr3, CSI_CSICR3); 348 __raw_writel(cr3, csi->regbase + CSI_CSICR3);
335} 349}
336EXPORT_SYMBOL(csi_dmareq_rff_disable); 350EXPORT_SYMBOL(csi_dmareq_rff_disable);
337 351
352struct csi_soc *csi_get_soc(int id)
353{
354 if (id >= CSI_MAX_NUM)
355 return ERR_PTR(-ENODEV);
356 else if (!csi_array[id].online)
357 return ERR_PTR(-ENODEV);
358 else
359 return &(csi_array[id]);
360}
361EXPORT_SYMBOL_GPL(csi_get_soc);
362
338static const struct of_device_id fsl_csi_dt_ids[] = { 363static const struct of_device_id fsl_csi_dt_ids[] = {
339 { .compatible = "fsl,imx6sl-csi", }, 364 { .compatible = "fsl,imx6sl-csi", },
340 { /* sentinel */ } 365 { /* sentinel */ }
@@ -345,6 +370,13 @@ static int csi_probe(struct platform_device *pdev)
345{ 370{
346 int ret = 0; 371 int ret = 0;
347 struct resource *res; 372 struct resource *res;
373 int id;
374
375 id = of_alias_get_id(pdev->dev.of_node, "csi");
376 if (id < 0) {
377 dev_dbg(&pdev->dev, "can not get alias id\n");
378 return id;
379 }
348 380
349 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 381 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
350 if (!res) { 382 if (!res) {
@@ -352,7 +384,10 @@ static int csi_probe(struct platform_device *pdev)
352 ret = -ENODEV; 384 ret = -ENODEV;
353 goto err; 385 goto err;
354 } 386 }
355 irq_nr = res->start; 387
388 csi = &csi_array[id];
389 csi->irq_nr = res->start;
390 csi->online = false;
356 391
357 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 392 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
358 if (!res) { 393 if (!res) {
@@ -360,8 +395,8 @@ static int csi_probe(struct platform_device *pdev)
360 ret = -ENODEV; 395 ret = -ENODEV;
361 goto err; 396 goto err;
362 } 397 }
363 csi_regbase = devm_ioremap(&pdev->dev, res->start, resource_size(res)); 398 csi->regbase = devm_ioremap(&pdev->dev, res->start, resource_size(res));
364 if (!csi_regbase) { 399 if (!csi->regbase) {
365 dev_err(&pdev->dev, "ioremap failed with csi base\n"); 400 dev_err(&pdev->dev, "ioremap failed with csi base\n");
366 ret = -ENOMEM; 401 ret = -ENOMEM;
367 goto err; 402 goto err;
@@ -385,11 +420,11 @@ static int csi_probe(struct platform_device *pdev)
385 } 420 }
386 421
387 csi_clk_enable(); 422 csi_clk_enable();
388 csihw_reset(); 423 csihw_reset(csi);
389 csi_init_interface(); 424 csi_init_interface(csi);
390 csi_dmareq_rff_disable(); 425 csi_dmareq_rff_disable(csi);
391 csi_clk_disable();
392 426
427 csi->online = true;
393err: 428err:
394 return ret; 429 return ret;
395} 430}
diff --git a/drivers/media/platform/mxc/capture/fsl_csi.h b/drivers/media/platform/mxc/capture/fsl_csi.h
index 78b393ef9151..2823ef4e2e50 100644
--- a/drivers/media/platform/mxc/capture/fsl_csi.h
+++ b/drivers/media/platform/mxc/capture/fsl_csi.h
@@ -110,30 +110,24 @@
110#define CSI_MCLK_I2C 8 110#define CSI_MCLK_I2C 8
111#endif 111#endif
112 112
113extern void __iomem *csi_regbase; 113#define CSI_CSICR1 0x0
114#define CSI_CSICR1 (csi_regbase) 114#define CSI_CSICR2 0x4
115#define CSI_CSICR2 (csi_regbase + 0x4) 115#define CSI_CSICR3 0x8
116#define CSI_CSICR3 (csi_regbase + 0x8) 116#define CSI_STATFIFO 0xC
117#define CSI_STATFIFO (csi_regbase + 0xC) 117#define CSI_CSIRXFIFO 0x10
118#define CSI_CSIRXFIFO (csi_regbase + 0x10) 118#define CSI_CSIRXCNT 0x14
119#define CSI_CSIRXCNT (csi_regbase + 0x14) 119#define CSI_CSISR 0x18
120#define CSI_CSISR (csi_regbase + 0x18) 120
121 121#define CSI_CSIDBG 0x1C
122#define CSI_CSIDBG (csi_regbase + 0x1C) 122#define CSI_CSIDMASA_STATFIFO 0x20
123#define CSI_CSIDMASA_STATFIFO (csi_regbase + 0x20) 123#define CSI_CSIDMATS_STATFIFO 0x24
124#define CSI_CSIDMATS_STATFIFO (csi_regbase + 0x24) 124#define CSI_CSIDMASA_FB1 0x28
125#define CSI_CSIDMASA_FB1 (csi_regbase + 0x28) 125#define CSI_CSIDMASA_FB2 0x2C
126#define CSI_CSIDMASA_FB2 (csi_regbase + 0x2C) 126#define CSI_CSIFBUF_PARA 0x30
127#define CSI_CSIFBUF_PARA (csi_regbase + 0x30) 127#define CSI_CSIIMAG_PARA 0x34
128#define CSI_CSIIMAG_PARA (csi_regbase + 0x34) 128
129 129#define CSI_CSICR18 0x48
130#define CSI_CSICR18 (csi_regbase + 0x48) 130#define CSI_CSICR19 0x4c
131#define CSI_CSICR19 (csi_regbase + 0x4c)
132
133static inline void csi_clear_status(unsigned long status)
134{
135 __raw_writel(status, CSI_CSISR);
136}
137 131
138struct csi_signal_cfg_t { 132struct csi_signal_cfg_t {
139 unsigned data_width:3; 133 unsigned data_width:3;
@@ -193,24 +187,39 @@ struct csi_config_t {
193 unsigned int rxcnt; 187 unsigned int rxcnt;
194}; 188};
195 189
190struct csi_soc {
191 bool online;
192 int irq_nr;
193 void __iomem *regbase;
194};
195
196typedef void (*csi_irq_callback_t) (void *data, unsigned long status); 196typedef void (*csi_irq_callback_t) (void *data, unsigned long status);
197 197
198void csi_init_interface(void); 198void csi_set_32bit_imagpara(cam_data *cam, int width, int height);
199void csi_set_32bit_imagpara(int width, int height); 199void csi_set_16bit_imagpara(cam_data *cam, int width, int height);
200void csi_set_16bit_imagpara(int width, int height); 200void csi_set_12bit_imagpara(cam_data *cam, int width, int height);
201void csi_set_12bit_imagpara(int width, int height); 201void csi_format_swap16(cam_data *cam, bool enable);
202void csi_format_swap16(bool enable);
203int csi_read_mclk_flag(void); 202int csi_read_mclk_flag(void);
204void csi_start_callback(void *data); 203void csi_start_callback(void *data);
205void csi_stop_callback(void *data); 204void csi_stop_callback(void *data);
206void csi_enable_int(int arg); 205void csi_enable_int(cam_data *cam, int arg);
207void csi_buf_stride_set(u32 stride); 206void csi_buf_stride_set(cam_data *cam, u32 stride);
208void csi_deinterlace_mode(int mode); 207void csi_deinterlace_mode(cam_data *cam, int mode);
209void csi_deinterlace_enable(bool enable); 208void csi_deinterlace_enable(cam_data *cam, bool enable);
210void csi_tvdec_enable(bool enable); 209void csi_tvdec_enable(cam_data *cam, bool enable);
211void csi_enable(int arg); 210void csi_enable(cam_data *cam, int arg);
212void csi_disable_int(void); 211void csi_disable_int(cam_data *cam);
213void csi_clk_enable(void); 212void csi_clk_enable(void);
214void csi_clk_disable(void); 213void csi_clk_disable(void);
215void csi_dmareq_rff_enable(void); 214void csi_dmareq_rff_enable(struct csi_soc *csi);
216void csi_dmareq_rff_disable(void); 215void csi_dmareq_rff_disable(struct csi_soc *csi);
216static inline int csi_read(struct csi_soc *csi, unsigned int offset)
217{
218 return __raw_readl(csi->regbase + offset);
219}
220void csi_write(struct csi_soc *csi, unsigned int value, unsigned int offset)
221{
222 __raw_writel(value, csi->regbase + offset);
223}
224
225struct csi_soc *csi_get_soc(int id);
diff --git a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
index 09a421f20f7e..b8ea5b9b2d27 100644
--- a/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
+++ b/drivers/media/platform/mxc/capture/mxc_v4l2_capture.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 2004-2013 Freescale Semiconductor, Inc. All Rights Reserved. 2 * Copyright 2004-2014 Freescale Semiconductor, Inc. All Rights Reserved.
3 */ 3 */
4 4
5/* 5/*
@@ -157,6 +157,8 @@ typedef struct _cam_data {
157 157
158 /* v4l2 format */ 158 /* v4l2 format */
159 struct v4l2_format v2f; 159 struct v4l2_format v2f;
160 struct v4l2_format input_fmt; /* camera in */
161 bool bswapenable;
160 int rotation; /* for IPUv1 and IPUv3, this means encoder rotation */ 162 int rotation; /* for IPUv1 and IPUv3, this means encoder rotation */
161 int vf_rotation; /* viewfinder rotation only for IPUv1 and IPUv3 */ 163 int vf_rotation; /* viewfinder rotation only for IPUv1 and IPUv3 */
162 struct v4l2_mxc_offset offset; 164 struct v4l2_mxc_offset offset;
@@ -219,6 +221,7 @@ typedef struct _cam_data {
219 struct v4l2_int_device *self; 221 struct v4l2_int_device *self;
220 int sensor_index; 222 int sensor_index;
221 void *ipu; 223 void *ipu;
224 void *csi_soc;
222 enum imx_v4l2_devtype devtype; 225 enum imx_v4l2_devtype devtype;
223 226
224 /* v4l2 buf elements related to PxP DMA */ 227 /* v4l2 buf elements related to PxP DMA */