msm-camera: Add support for YV12 preview format

Enable camera driver to output preview frames in YV12 format.

Change-Id: Ib4e358460eb922c6a06314682380c4de30f81319
Signed-off-by: Alekhya,Monika <malekh@codeaurora.org>
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index fd282d5..8961c79 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -155,8 +155,12 @@
 
 struct msm_vpe_phy_info {
 	uint32_t sbuf_phy;
-	uint32_t y_phy;
-	uint32_t cbcr_phy;
+	uint32_t planar0_off;
+	uint32_t planar1_off;
+	uint32_t planar2_off;
+	uint32_t p0_phy;
+	uint32_t p1_phy;
+	uint32_t p2_phy;
 	uint8_t  output_id; /* VFE31_OUTPUT_MODE_PT/S/V */
 	uint32_t frame_id;
 };
@@ -193,6 +197,7 @@
 #define VFE31_OUTPUT_MODE_V (0x1 << 2)
 #define VFE31_OUTPUT_MODE_P (0x1 << 3)
 #define VFE31_OUTPUT_MODE_T (0x1 << 4)
+#define VFE31_OUTPUT_MODE_P_ALL_CHNLS (0x1 << 5)
 
 #define CSI_EMBED_DATA 0x12
 #define CSI_YUV422_8  0x1E
@@ -206,8 +211,12 @@
 
 struct msm_vfe_phy_info {
 	uint32_t sbuf_phy;
-	uint32_t y_phy;
-	uint32_t cbcr_phy;
+	uint32_t planar0_off;
+	uint32_t planar1_off;
+	uint32_t planar2_off;
+	uint32_t p0_phy;
+	uint32_t p1_phy;
+	uint32_t p2_phy;
 	uint8_t  output_id; /* VFE31_OUTPUT_MODE_PT/S/V */
 	uint32_t frame_id;
 };
@@ -238,8 +247,8 @@
 };
 
 struct msm_vpe_buf_info {
-	uint32_t y_phy;
-	uint32_t cbcr_phy;
+	uint32_t p0_phy;
+	uint32_t p1_phy;
 	struct   timespec ts;
 	uint32_t frame_id;
 	struct	 video_crop_t vpe_crop;
@@ -303,7 +312,7 @@
 struct msm_camvpe_fn {
 	int (*vpe_reg)(struct msm_vpe_callback *);
 	int (*vpe_cfg_update) (void *);
-	void (*send_frame_to_vpe) (uint32_t y_phy, uint32_t cbcr_phy,
+	void (*send_frame_to_vpe) (uint32_t planar0_off, uint32_t planar1_off,
 		struct timespec *ts, int output_id);
 	int (*vpe_config)(struct msm_vpe_cfg_cmd *, void *);
 	void (*vpe_cfg_offset)(int frame_pack, uint32_t pyaddr,
diff --git a/drivers/media/video/msm/msm_camera.c b/drivers/media/video/msm/msm_camera.c
index 65b33c2..dbf0eae 100644
--- a/drivers/media/video/msm/msm_camera.c
+++ b/drivers/media/video/msm/msm_camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -279,16 +279,18 @@
 {
 	if (info->offset < len &&
 	    info->offset + info->len <= len &&
-	    info->y_off < len &&
-	    info->cbcr_off < len)
+	    info->planar0_off < len &&
+	    info->planar1_off < len &&
+	    info->planar2_off < len)
 		return 0;
 
-	pr_err("%s: check failed: off %d len %d y %d cbcr %d (total len %d)\n",
+	pr_err("%s: check failed: off %d len %d y 0x%x cbcr_p1 0x%x p2_add 0x%x(total len %d)\n",
 		__func__,
 		info->offset,
 		info->len,
-		info->y_off,
-		info->cbcr_off,
+		info->planar0_off,
+		info->planar1_off,
+		info->planar2_off,
 		len);
 	return -EINVAL;
 }
@@ -352,8 +354,10 @@
 
 	hlist_add_head(&(region->list), ptype);
 	spin_unlock_irqrestore(pmem_spinlock, flags);
-	CDBG("%s: type %d, paddr 0x%lx, vaddr 0x%lx\n",
-		__func__, info->type, paddr, (unsigned long)info->vaddr);
+	CDBG("%s: type %d, paddr 0x%lx, vaddr 0x%lx p0_add = 0x%x"
+		"p1_addr = 0x%x p2_addr = 0x%x\n",
+		__func__, info->type, paddr, (unsigned long)info->vaddr,
+		info->planar0_off, info->planar1_off, info->planar2_off);
 	return 0;
 out2:
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
@@ -439,8 +443,9 @@
 }
 
 static int msm_pmem_frame_ptov_lookup(struct msm_sync *sync,
-		unsigned long pyaddr,
-		unsigned long pcbcraddr,
+		unsigned long p0addr,
+		unsigned long p1addr,
+		unsigned long p2addr,
 		struct msm_pmem_info *pmem_info,
 		int clear_active)
 {
@@ -450,10 +455,10 @@
 
 	spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
 	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
-		if (pyaddr == (region->paddr + region->info.y_off) &&
-				pcbcraddr == (region->paddr +
-						region->info.cbcr_off) &&
-				region->info.active) {
+		if (p0addr == (region->paddr + region->info.planar0_off) &&
+			p1addr == (region->paddr + region->info.planar1_off) &&
+			p2addr == (region->paddr + region->info.planar2_off) &&
+			region->info.active) {
 			/* offset since we could pass vaddr inside
 			 * a registerd pmem buffer
 			 */
@@ -466,12 +471,13 @@
 		}
 	}
 	/* After lookup failure, dump all the list entries... */
-	pr_err("%s, for pyaddr 0x%lx, pcbcraddr 0x%lx\n",
-			__func__, pyaddr, pcbcraddr);
+	pr_err("%s, for plane0 addr = 0x%lx, plane1 addr = 0x%lx  plane2 addr = 0x%lx\n",
+			__func__, p0addr, p1addr, p2addr);
 	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
-		pr_err("listed pyaddr 0x%lx, pcbcraddr 0x%lx, active = %d",
-				(region->paddr + region->info.y_off),
-				(region->paddr + region->info.cbcr_off),
+		pr_err("listed p0addr 0x%lx, p1addr 0x%lx, p2addr 0x%lx, active = %d",
+				(region->paddr + region->info.planar0_off),
+				(region->paddr + region->info.planar1_off),
+				(region->paddr + region->info.planar2_off),
 				region->info.active);
 	}
 
@@ -480,7 +486,7 @@
 }
 
 static int msm_pmem_frame_ptov_lookup2(struct msm_sync *sync,
-		unsigned long pyaddr,
+		unsigned long p0_phy,
 		struct msm_pmem_info *pmem_info,
 		int clear_active)
 {
@@ -490,7 +496,7 @@
 
 	spin_lock_irqsave(&sync->pmem_frame_spinlock, flags);
 	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
-		if (pyaddr == (region->paddr + region->info.y_off) &&
+		if (p0_phy == (region->paddr + region->info.planar0_off) &&
 				region->info.active) {
 			/* offset since we could pass vaddr inside
 			 * a registerd pmem buffer
@@ -541,8 +547,8 @@
 }
 
 static unsigned long msm_pmem_frame_vtop_lookup(struct msm_sync *sync,
-		unsigned long buffer,
-		uint32_t yoff, uint32_t cbcroff, int fd, int change_flag)
+		unsigned long buffer, uint32_t p0_off, uint32_t p1_off,
+		uint32_t p2_off, int fd, int change_flag)
 {
 	struct msm_pmem_region *region;
 	struct hlist_node *node, *n;
@@ -552,8 +558,9 @@
 	hlist_for_each_entry_safe(region,
 		node, n, &sync->pmem_frames, list) {
 		if (((unsigned long)(region->info.vaddr) == buffer) &&
-				(region->info.y_off == yoff) &&
-				(region->info.cbcr_off == cbcroff) &&
+				(region->info.planar0_off == p0_off) &&
+				(region->info.planar1_off == p1_off) &&
+				(region->info.planar2_off == p2_off) &&
 				(region->info.fd == fd) &&
 				(region->info.active == 0)) {
 			if (change_flag)
@@ -564,13 +571,16 @@
 		}
 	}
 	/* After lookup failure, dump all the list entries... */
-	pr_err("%s, failed for vaddr 0x%lx, yoff %d cbcroff %d\n",
-			__func__, buffer, yoff, cbcroff);
+	pr_err("%s, failed for vaddr 0x%lx, p0_off %d p1_off %d\n",
+			__func__, buffer, p0_off, p1_off);
 	hlist_for_each_entry_safe(region, node, n, &sync->pmem_frames, list) {
-		pr_err("listed vaddr 0x%p, cbcroff %d, active = %d",
-				(region->info.vaddr),
-				(region->info.cbcr_off),
-				region->info.active);
+		pr_err("%s, listed vaddr 0x%lx, r_p0 = 0x%x p0_off 0x%x"
+			"r_p1 = 0x%x, p1_off 0x%x, r_p2 = 0x%x, p2_off = 0x%x"
+			" active = %d\n", __func__, buffer,
+			region->info.planar0_off,
+			p0_off, region->info.planar1_off,
+			p1_off, region->info.planar2_off, p2_off,
+			region->info.active);
 	}
 
 	spin_unlock_irqrestore(&sync->pmem_frame_spinlock, flags);
@@ -741,33 +751,36 @@
 
 	vdata = (struct msm_vfe_resp *)(qcmd->command);
 	pphy = &vdata->phy;
+	CDBG("%s, pphy->p2_phy = 0x%x\n", __func__, pphy->p2_phy);
 
 	rc = msm_pmem_frame_ptov_lookup(sync,
-			pphy->y_phy,
-			pphy->cbcr_phy,
+			pphy->p0_phy,
+			pphy->p1_phy,
+			pphy->p2_phy,
 			&pmem_info,
 			1); /* Clear the active flag */
 
 	if (rc < 0) {
-		pr_err("%s: cannot get frame, invalid lookup address "
-			"y %x cbcr %x\n",
-			__func__,
-			pphy->y_phy,
-			pphy->cbcr_phy);
+		pr_err("%s: cannot get frame, invalid lookup address"
+		"plane0 add %x plane1 add %x plane2 add%x\n",
+		__func__,
+		pphy->p0_phy,
+		pphy->p1_phy,
+		pphy->p2_phy);
 		goto err;
 	}
 
 	frame->ts = qcmd->ts;
 	frame->buffer = (unsigned long)pmem_info.vaddr;
-	frame->y_off = pmem_info.y_off;
-	frame->cbcr_off = pmem_info.cbcr_off;
+	frame->planar0_off = pmem_info.planar0_off;
+	frame->planar1_off = pmem_info.planar1_off;
+	frame->planar2_off = pmem_info.planar2_off;
 	frame->fd = pmem_info.fd;
 	frame->path = vdata->phy.output_id;
 	frame->frame_id = vdata->phy.frame_id;
-
-	CDBG("%s: y %x, cbcr %x, qcmd %x, virt_addr %x\n",
-		__func__,
-		pphy->y_phy, pphy->cbcr_phy, (int) qcmd, (int) frame->buffer);
+	CDBG("%s: plane0 %x, plane1 %x, plane2 %x,qcmd %x, virt_addr %x\n",
+		__func__, pphy->p0_phy, pphy->p1_phy, pphy->p2_phy,
+		(int) qcmd, (int) frame->buffer);
 
 err:
 	free_qcmd(qcmd);
@@ -1078,8 +1091,8 @@
 		return -EINVAL;
 	}
 
-	rc = msm_pmem_frame_ptov_lookup(sync, data->phy.y_phy,
-			data->phy.cbcr_phy, &pinfo,
+	rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
+			data->phy.p1_phy, data->phy.p2_phy, &pinfo,
 			0); /* do not clear the active flag */
 
 	if (rc < 0) {
@@ -1088,8 +1101,8 @@
 	}
 
 	buf.fmain.buffer = (unsigned long)pinfo.vaddr;
-	buf.fmain.y_off = pinfo.y_off;
-	buf.fmain.cbcr_off = pinfo.cbcr_off;
+	buf.fmain.planar0_off = pinfo.planar0_off;
+	buf.fmain.planar1_off = pinfo.planar1_off;
 	buf.fmain.fd = pinfo.fd;
 
 	CDBG("%s: buf 0x%x fd %d\n", __func__, (unsigned int)buf.fmain.buffer,
@@ -1119,14 +1132,14 @@
 		buf.type = OUTPUT_TYPE_ST_R;
 	} else {
 		if (se->resptype == MSM_CAM_RESP_STEREO_OP_1) {
-			rc = msm_pmem_frame_ptov_lookup(sync, data->phy.y_phy,
-					data->phy.cbcr_phy, &pinfo,
-					1);  /* do clear the active flag */
+			rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
+				data->phy.p1_phy, data->phy.p2_phy, &pinfo,
+				1);  /* do clear the active flag */
 			buf.buf_info.path = path;
 		} else if (se->resptype == MSM_CAM_RESP_STEREO_OP_2) {
-			rc = msm_pmem_frame_ptov_lookup(sync, data->phy.y_phy,
-					data->phy.cbcr_phy, &pinfo,
-					0); /* do not clear the active flag */
+			rc = msm_pmem_frame_ptov_lookup(sync, data->phy.p0_phy,
+				data->phy.p1_phy, data->phy.p2_phy, &pinfo,
+				0); /* do not clear the active flag */
 			buf.buf_info.path = path;
 		} else
 			CDBG("%s: Invalid resptype = %d\n", __func__,
@@ -1184,8 +1197,9 @@
 
 		buf.buf_info.buffer = (unsigned long)pinfo.vaddr;
 		buf.buf_info.phy_offset = pinfo.offset;
-		buf.buf_info.y_off = pinfo.y_off;
-		buf.buf_info.cbcr_off = pinfo.cbcr_off;
+		buf.buf_info.planar0_off = pinfo.planar0_off;
+		buf.buf_info.planar1_off = pinfo.planar1_off;
+		buf.buf_info.planar2_off = pinfo.planar2_off;
 		buf.buf_info.fd = pinfo.fd;
 
 		CDBG("%s: buf 0x%x fd %d\n", __func__,
@@ -1837,6 +1851,7 @@
 		}
 		break;
 
+	case CMD_AXI_CFG_VIDEO_ALL_CHNLS:
 	case CMD_AXI_CFG_VIDEO:
 		pmem_type = MSM_PMEM_PREVIEW;
 		axi_data.bufnum1 =
@@ -1889,6 +1904,7 @@
 		}
 		break;
 
+	case CMD_AXI_CFG_ZSL_ALL_CHNLS:
 	case CMD_AXI_CFG_ZSL:
 		CDBG("%s, CMD_AXI_CFG_ZSL, type = %d\n", __func__,
 			cfgcmd->cmd_type);
@@ -2044,7 +2060,7 @@
 	/* Change the active flag. */
 	pphy = msm_pmem_frame_vtop_lookup(sync,
 		pb->buffer,
-		pb->y_off, pb->cbcr_off, pb->fd, 1);
+		pb->planar0_off, pb->planar1_off, pb->planar2_off, pb->fd, 1);
 
 	if (pphy != 0) {
 		CDBG("%s: rel: vaddr %lx, paddr %lx\n",
@@ -2072,7 +2088,7 @@
 
 	pphy = msm_pmem_frame_vtop_lookup(sync,
 		pb->buffer,
-		pb->y_off, pb->cbcr_off, pb->fd, 1);
+		pb->planar0_off, pb->planar1_off, pb->planar2_off, pb->fd, 1);
 
 	if (pphy != 0) {
 		CDBG("%s: rel: vaddr %lx, paddr %lx\n",
@@ -2295,6 +2311,8 @@
 	case CMD_AXI_CFG_SNAP:
 	case CMD_RAW_PICT_AXI_CFG:
 	case CMD_AXI_CFG_ZSL:
+	case CMD_AXI_CFG_VIDEO_ALL_CHNLS:
+	case CMD_AXI_CFG_ZSL_ALL_CHNLS:
 		CDBG("%s, cfgcmd.cmd_type = %d\n", __func__, cfgcmd.cmd_type);
 		return msm_frame_axi_cfg(sync, &cfgcmd);
 
@@ -2340,21 +2358,21 @@
 		pphy = &vdata->phy;
 
 		rc = msm_pmem_frame_ptov_lookup2(sync,
-				pphy->y_phy,
+				pphy->p0_phy,
 				&pmem_info,
 				1); /* mark pic frame in use */
 
 		if (rc < 0) {
 			pr_err("%s: cannot get pic frame, invalid lookup"
-				" address y %x cbcr %x\n",
-				__func__, pphy->y_phy, pphy->cbcr_phy);
+				" address p0_phy add  %x p1_phy add%x\n",
+				__func__, pphy->p0_phy, pphy->p1_phy);
 			goto err;
 		}
 
 		frame->ts = qcmd->ts;
 		frame->buffer = (unsigned long)pmem_info.vaddr;
-		frame->y_off = pmem_info.y_off;
-		frame->cbcr_off = pmem_info.cbcr_off;
+		frame->planar0_off = pmem_info.planar0_off;
+		frame->planar1_off = pmem_info.planar1_off;
 		frame->fd = pmem_info.fd;
 		if (sync->stereocam_enabled &&
 			sync->stereo_state != STEREO_RAW_SNAP_STARTED) {
@@ -2365,20 +2383,20 @@
 		} else
 			frame->path = vdata->phy.output_id;
 
-		CDBG("%s: y %x, cbcr %x, qcmd %x, virt_addr %x\n",
-			__func__, pphy->y_phy,
-			pphy->cbcr_phy, (int) qcmd, (int) frame->buffer);
+		CDBG("%s:p0_phy add %x, p0_phy add %x, qcmd %x, virt_addr %x\n",
+			__func__, pphy->p0_phy,
+			pphy->p1_phy, (int) qcmd, (int) frame->buffer);
 	} else { /* PP */
 		pframe = (struct msm_frame *)(qcmd->command);
 		frame->ts = qcmd->ts;
 		frame->buffer = pframe->buffer;
-		frame->y_off = pframe->y_off;
-		frame->cbcr_off = pframe->cbcr_off;
+		frame->planar0_off = pframe->planar0_off;
+		frame->planar1_off = pframe->planar1_off;
 		frame->fd = pframe->fd;
 		frame->path = pframe->path;
 		CDBG("%s: PP y_off %x, cbcr_off %x, path %d vaddr 0x%x\n",
-			__func__, frame->y_off, frame->cbcr_off, frame->path,
-			(int) frame->buffer);
+		__func__, frame->planar0_off, frame->planar1_off, frame->path,
+		(int) frame->buffer);
 	}
 
 err:
@@ -2604,13 +2622,13 @@
 			vfe_rp = (struct msm_vfe_resp *)qcmd->command;
 
 			CDBG("%s: Left Py = 0x%x y_off = %d cbcr_off = %d\n",
-				__func__, vfe_rp->phy.y_phy,
-				stereo_frame_half.L.buf_y_off,
-				stereo_frame_half.L.buf_cbcr_off);
+				__func__, vfe_rp->phy.p0_phy,
+				stereo_frame_half.L.buf_p0_off,
+				stereo_frame_half.L.buf_p1_off);
 
 			sync->vpefn.vpe_cfg_offset(stereo_frame_half.packing,
-			vfe_rp->phy.y_phy + stereo_frame_half.L.buf_y_off,
-			vfe_rp->phy.y_phy + stereo_frame_half.L.buf_cbcr_off,
+			vfe_rp->phy.p0_phy + stereo_frame_half.L.buf_p0_off,
+			vfe_rp->phy.p1_phy + stereo_frame_half.L.buf_p1_off,
 			&(qcmd->ts), OUTPUT_TYPE_ST_L, stereo_frame_half.L,
 			stereo_frame_half.frame_id);
 
@@ -2626,14 +2644,15 @@
 
 			st_pphy = msm_pmem_frame_vtop_lookup(sync,
 				stereo_frame_half.buf_info.buffer,
-				stereo_frame_half.buf_info.y_off,
-				stereo_frame_half.buf_info.cbcr_off,
+				stereo_frame_half.buf_info.planar0_off,
+				stereo_frame_half.buf_info.planar1_off,
+				stereo_frame_half.buf_info.planar2_off,
 				stereo_frame_half.buf_info.fd,
 				0); /* Do not change the active flag. */
 
 			sync->vpefn.vpe_cfg_offset(stereo_frame_half.packing,
-				st_pphy + stereo_frame_half.R.buf_y_off,
-				st_pphy + stereo_frame_half.R.buf_cbcr_off,
+				st_pphy + stereo_frame_half.R.buf_p0_off,
+				st_pphy + stereo_frame_half.R.buf_p1_off,
 				NULL, OUTPUT_TYPE_ST_R, stereo_frame_half.R,
 				stereo_frame_half.frame_id);
 
@@ -3332,10 +3351,10 @@
 	switch (vdata->type) {
 	case VFE_MSG_OUTPUT_P:
 		if (sync->pp_mask & PP_PREV) {
-			CDBG("%s: PP_PREV in progress: phy_y %x phy_cbcr %x\n",
+			CDBG("%s: PP_PREV in progress: p0_add %x p1_add %x\n",
 				__func__,
-				vdata->phy.y_phy,
-				vdata->phy.cbcr_phy);
+				vdata->phy.p0_phy,
+				vdata->phy.p1_phy);
 			spin_lock_irqsave(&pp_prev_spinlock, flags);
 			if (sync->pp_prev)
 				CDBG("%s: overwriting pp_prev!\n",
@@ -3493,8 +3512,8 @@
 					vdata->vpe_bf.vpe_crop =
 				*(struct video_crop_t *)(sync->cropinfo);
 
-				vdata->vpe_bf.y_phy = vdata->phy.y_phy;
-				vdata->vpe_bf.cbcr_phy = vdata->phy.cbcr_phy;
+				vdata->vpe_bf.p0_phy = vdata->phy.p0_phy;
+				vdata->vpe_bf.p1_phy = vdata->phy.p1_phy;
 				vdata->vpe_bf.ts = (qcmd->ts);
 				vdata->vpe_bf.frame_id = vdata->phy.frame_id;
 				qcmd->command = vdata;
@@ -3506,8 +3525,8 @@
 					"= %ld\n", __func__, qcmd->ts.tv_nsec);
 
 				sync->vpefn.send_frame_to_vpe(
-					vdata->phy.y_phy,
-					vdata->phy.cbcr_phy,
+					vdata->phy.p0_phy,
+					vdata->phy.p1_phy,
 					&(qcmd->ts), OUTPUT_TYPE_V);
 
 				free_qcmd(qcmd);
diff --git a/drivers/media/video/msm/msm_mem.c b/drivers/media/video/msm/msm_mem.c
index c13e7e5..b631981 100644
--- a/drivers/media/video/msm/msm_mem.c
+++ b/drivers/media/video/msm/msm_mem.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -84,16 +84,16 @@
 {
 	if (info->offset < len &&
 		info->offset + info->len <= len &&
-		info->y_off < len &&
-		info->cbcr_off < len)
+		info->planar0_off < len &&
+		info->planar1_off < len)
 		return 0;
 
 	pr_err("%s: check failed: off %d len %d y %d cbcr %d (total len %d)\n",
 						__func__,
 						info->offset,
 						info->len,
-						info->y_off,
-						info->cbcr_off,
+						info->planar0_off,
+						info->planar1_off,
 						len);
 	return -EINVAL;
 }
diff --git a/drivers/media/video/msm/msm_vfe31.c b/drivers/media/video/msm/msm_vfe31.c
index b22b6c5..2b3732c 100644
--- a/drivers/media/video/msm/msm_vfe31.c
+++ b/drivers/media/video/msm/msm_vfe31.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -337,10 +337,12 @@
 			break;
 		}
 		pinfo->output_id = outid;
-		pinfo->y_phy =
-			((struct vfe_message *)data)->_u.msgOut.yBuffer;
-		pinfo->cbcr_phy =
-			((struct vfe_message *)data)->_u.msgOut.cbcrBuffer;
+		pinfo->p0_phy =
+			((struct vfe_message *)data)->_u.msgOut.p0_addr;
+		pinfo->p1_phy =
+			((struct vfe_message *)data)->_u.msgOut.p1_addr;
+		pinfo->p2_phy =
+			((struct vfe_message *)data)->_u.msgOut.p2_addr;
 
 		pinfo->frame_id =
 		((struct vfe_message *)data)->_u.msgOut.frameCounter;
@@ -458,8 +460,8 @@
 		GFP_ATOMIC);
 }
 
-static void vfe_send_outmsg(uint8_t msgid, uint32_t pyaddr,
-	uint32_t pcbcraddr)
+static void vfe_send_outmsg(uint8_t msgid, uint32_t p0_addr,
+	uint32_t p1_addr, uint32_t p2_addr)
 {
 	struct vfe_message msg;
 	uint8_t outid;
@@ -485,9 +487,10 @@
 		break;
 	}
 	msg._u.msgOut.output_id   = msgid;
-	msg._u.msgOut.yBuffer     = pyaddr;
-	msg._u.msgOut.cbcrBuffer  = pcbcraddr;
-
+	msg._u.msgOut.p0_addr     = p0_addr;
+	msg._u.msgOut.p1_addr     = p1_addr;
+	msg._u.msgOut.p2_addr     = p2_addr;
+	CDBG("%s p2_addr = 0x%x\n", __func__, p2_addr);
 	vfe31_proc_ops(msgid, &msg, sizeof(struct vfe_message));
 	return;
 }
@@ -542,7 +545,7 @@
 }
 
 static int vfe31_add_free_buf2(struct vfe31_output_ch *outch,
-	uint32_t paddr, uint32_t y_off, uint32_t cbcr_off)
+	uint32_t paddr, uint32_t p0_off, uint32_t p1_off, uint32_t p2_off)
 {
 	struct vfe31_free_buf *free_buf = NULL;
 	unsigned long flags = 0;
@@ -552,20 +555,23 @@
 
 	spin_lock_irqsave(&outch->free_buf_lock, flags);
 	free_buf->paddr = paddr;
-	free_buf->y_off = y_off;
-	free_buf->cbcr_off = cbcr_off;
+	free_buf->planar0_off = p0_off;
+	free_buf->planar1_off = p1_off;
+	free_buf->planar2_off = p2_off;
 	list_add_tail(&free_buf->node, &outch->free_buf_head);
 
 	CDBG("%s: free_buf paddr = 0x%x, y_off = %d, cbcr_off = %d\n",
-		__func__, free_buf->paddr, free_buf->y_off,
-		free_buf->cbcr_off);
+		__func__, free_buf->paddr, free_buf->planar0_off,
+		free_buf->planar1_off);
 	spin_unlock_irqrestore(&outch->free_buf_lock, flags);
 	return 0;
 }
 
 #define vfe31_add_free_buf(outch, regptr) \
-	vfe31_add_free_buf2(outch, regptr->paddr, regptr->info.y_off,	\
-		regptr->info.cbcr_off)
+	vfe31_add_free_buf2(outch, regptr->paddr, \
+	regptr->info.planar0_off,	\
+	regptr->info.planar1_off,	\
+	regptr->info.planar2_off)
 
 #define vfe31_free_buf_available(outch) \
 	(!list_empty(&outch.free_buf_head))
@@ -662,10 +668,10 @@
 
 		for (i = 0; i < 2; i++) {
 			p1 = ao + 6 + i;    /* wm0 for y  */
-			*p1 = (regp1->paddr + regp1->info.y_off);
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
 
 			p1 = ao + 12 + i;  /* wm1 for cbcr */
-			*p1 = (regp1->paddr + regp1->info.cbcr_off);
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
 			regp1++;
 		}
 		ret = vfe31_add_free_buf(outp1, regp1);
@@ -694,47 +700,47 @@
 		/*  Parse the buffers!!! */
 		if (ad->bufnum2 == 1) {	/* assuming bufnum1 = bufnum2 */
 			p1 = ao + 6;   /* wm0 ping */
-			*p1++ = (regp1->paddr + regp1->info.y_off);
+			*p1++ = (regp1->paddr + regp1->info.planar0_off);
 
 			/* this is to duplicate ping address to pong.*/
-			*p1 = (regp1->paddr + regp1->info.y_off);
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
 
 			p1 = ao + 30;  /* wm4 ping */
-			*p1++ = (regp1->paddr + regp1->info.cbcr_off);
+			*p1++ = (regp1->paddr + regp1->info.planar1_off);
 			CDBG("%s: regp1->info.cbcr_off = 0x%x\n", __func__,
-						 regp1->info.cbcr_off);
+						 regp1->info.planar1_off);
 
 			/* this is to duplicate ping address to pong.*/
-			*p1 = (regp1->paddr + regp1->info.cbcr_off);
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
 
 			p1 = ao + 12;   /* wm1 ping */
-			*p1++ = (regp2->paddr + regp2->info.y_off);
+			*p1++ = (regp2->paddr + regp2->info.planar0_off);
 
 			/* pong = ping,*/
-			*p1 = (regp2->paddr + regp2->info.y_off);
+			*p1 = (regp2->paddr + regp2->info.planar0_off);
 
 			p1 = ao + 36;  /* wm5 */
-			*p1++ = (regp2->paddr + regp2->info.cbcr_off);
+			*p1++ = (regp2->paddr + regp2->info.planar1_off);
 			CDBG("%s: regp2->info.cbcr_off = 0x%x\n", __func__,
-						 regp2->info.cbcr_off);
+						 regp2->info.planar1_off);
 
 			/* pong = ping,*/
-			*p1 = (regp2->paddr + regp2->info.cbcr_off);
+			*p1 = (regp2->paddr + regp2->info.planar1_off);
 		} else { /* more than one snapshot */
 			/* first fill ping & pong */
 			for (i = 0; i < 2; i++) {
 				p1 = ao + 6 + i;    /* wm0 for y  */
-				*p1 = (regp1->paddr + regp1->info.y_off);
+				*p1 = (regp1->paddr + regp1->info.planar0_off);
 				p1 = ao + 30 + i;  /* wm4 for cbcr */
-				*p1 = (regp1->paddr + regp1->info.cbcr_off);
+				*p1 = (regp1->paddr + regp1->info.planar1_off);
 				regp1--;
 			}
 
 			for (i = 0; i < 2; i++) {
 				p2 = ao + 12 + i;    /* wm1 for y  */
-				*p2 = (regp2->paddr + regp2->info.y_off);
+				*p2 = (regp2->paddr + regp2->info.planar0_off);
 				p2 = ao + 36 + i;  /* wm5 for cbcr */
-				*p2 = (regp2->paddr + regp2->info.cbcr_off);
+				*p2 = (regp2->paddr + regp2->info.planar1_off);
 				regp2--;
 			}
 
@@ -783,25 +789,25 @@
 		/* first fill ping & pong */
 		for (i = 0; i < 2; i++) {
 			p1 = ao + 6 + i;    /* wm0 for y  */
-			*p1 = (regp1->paddr + regp1->info.y_off);
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
 			p1 = ao + 30 + i;  /* wm4 for cbcr */
-			*p1 = (regp1->paddr + regp1->info.cbcr_off);
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
 			regp1++;
 		}
 
 		for (i = 0; i < 2; i++) {
 			p2 = ao + 12 + i;    /* wm1 for y  */
-			*p2 = (regp2->paddr + regp2->info.y_off);
+			*p2 = (regp2->paddr + regp2->info.planar0_off);
 			p2 = ao + 36 + i;  /* wm5 for cbcr */
-			*p2 = (regp2->paddr + regp2->info.cbcr_off);
+			*p2 = (regp2->paddr + regp2->info.planar1_off);
 			regp2++;
 		}
 
 		for (i = 0; i < 2; i++) {
 			p3 = ao + 18 + i;    /* wm2 for y  */
-			*p3 = (regp3->paddr + regp3->info.y_off);
+			*p3 = (regp3->paddr + regp3->info.planar0_off);
 			p3 = ao + 42 + i;  /* wm6 for cbcr */
-			*p3 = (regp3->paddr + regp3->info.cbcr_off);
+			*p3 = (regp3->paddr + regp3->info.planar1_off);
 			regp3++;
 		}
 
@@ -827,6 +833,80 @@
 		}
 		break;
 
+	case OUTPUT_ZSL_ALL_CHNLS:
+		CDBG("%s: OUTPUT_ZSL_ALL_CHNLS", __func__);
+		CDBG("%s: %d %d %d", __func__, ad->bufnum1, ad->bufnum2,
+			ad->bufnum3);
+		/* use wm0& 4 for postview, wm1&5 for preview.*/
+		/* use wm2& 6 for main img */
+		if ((ad->bufnum1 < 1) || (ad->bufnum2 < 1) || (ad->bufnum3 < 1))
+			return -EINVAL;
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_S;  /* main image.*/
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_P_ALL_CHNLS;  /* preview. */
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_T;  /* thumbnail. */
+
+		/* this is preview buffer. */
+		regp1 = &(ad->region[0]);
+		/* this is thumbnail buffer. */
+		regp2 = &(ad->region[ad->bufnum1]);
+		/* this is main image buffer. */
+		regp3 = &(ad->region[ad->bufnum1+ad->bufnum2]);
+		outp1 = &(vfe31_ctrl->outpath.out0);
+		outp2 = &(vfe31_ctrl->outpath.out1);
+		outp3 = &(vfe31_ctrl->outpath.out2);
+
+		/*  Parse the buffers!!! */
+		/* first fill ping & pong */
+		for (i = 0; i < 2; i++) {
+			p1 = ao + 6 + i;    /* wm0 for y  */
+			*p1 = (regp2->paddr + regp2->info.planar0_off);
+			p1 = ao + 12 + i;  /* wm1 for cbcr */
+			*p1 = (regp2->paddr + regp2->info.planar1_off);
+			regp2++;
+		}
+
+		for (i = 0; i < 2; i++) {
+			p2 = ao + 30 + i;    /* wm4 for y  */
+			*p2 = (regp1->paddr + regp1->info.planar0_off);
+			p2 = ao + 36 + i;  /* wm5 for cbcr */
+			*p2 = (regp1->paddr + regp1->info.planar1_off);
+			p2 = ao + 42 + i;  /* wm5 for cbcr */
+			*p2 = (regp1->paddr + regp1->info.planar2_off);
+			regp1++;
+		}
+
+		for (i = 0; i < 2; i++) {
+			p3 = ao + 18 + i;    /* wm2 for y  */
+			*p3 = (regp3->paddr + regp3->info.planar0_off);
+			p3 = ao + 24 + i;  /* wm3 for cbcr */
+			*p3 = (regp3->paddr + regp3->info.planar1_off);
+			regp3++;
+		}
+		for (i = 2; i < ad->bufnum1; i++) {
+			ret = vfe31_add_free_buf(outp1, regp1);
+			if (ret < 0)
+				return ret;
+			regp1++;
+		}
+
+		for (i = 2; i < ad->bufnum2; i++) {
+			ret = vfe31_add_free_buf(outp2, regp2);
+			if (ret < 0)
+				return ret;
+			regp2++;
+		}
+
+		for (i = 2; i < ad->bufnum3; i++) {
+			ret = vfe31_add_free_buf(outp3, regp3);
+			if (ret < 0)
+				return ret;
+			regp3++;
+		}
+		break;
+
 	case OUTPUT_1_AND_3: {
 		/* use wm0&4 for preview, wm1&5 for video.*/
 		if ((ad->bufnum1 < 2) || (ad->bufnum2 < 2))
@@ -849,19 +929,19 @@
 
 		for (i = 0; i < 2; i++) {
 			p1 = ao + 6 + i;    /* wm0 for y  */
-			*p1 = (regp1->paddr + regp1->info.y_off);
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
 
 			p1 = ao + 30 + i;  /* wm4 for cbcr */
-			*p1 = (regp1->paddr + regp1->info.cbcr_off);
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
 			regp1++;
 		}
 
 		for (i = 0; i < 2; i++) {
 			p2 = ao + 12 + i;    /* wm1 for y  */
-			*p2 = (regp2->paddr + regp2->info.y_off);
+			*p2 = (regp2->paddr + regp2->info.planar0_off);
 
 			p2 = ao + 36 + i;  /* wm5 for cbcr */
-			*p2 = (regp2->paddr + regp2->info.cbcr_off);
+			*p2 = (regp2->paddr + regp2->info.planar1_off);
 			regp2++;
 		}
 		for (i = 2; i < ad->bufnum1; i++) {
@@ -879,6 +959,52 @@
 		}
 	}
 		break;
+
+	case OUTPUT_VIDEO_ALL_CHNLS: {
+		/* use wm0&4 for preview, wm1&5 for video.*/
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_V;  /* video*/
+		vfe31_ctrl->outpath.output_mode |=
+			VFE31_OUTPUT_MODE_P_ALL_CHNLS;
+		regp1 = &(ad->region[0]);
+		regp2 = &(ad->region[ad->bufnum1]);
+		outp1 = &(vfe31_ctrl->outpath.out0);
+		outp2 = &(vfe31_ctrl->outpath.out2);
+
+		for (i = 0; i < 2; i++) {
+			p1 = ao + 6 + i;    /* wm0 for y  */
+			*p1 = (regp1->paddr + regp1->info.planar0_off);
+
+			p1 = ao + 12 + i;  /* wm1 for cbcr */
+			*p1 = (regp1->paddr + regp1->info.planar1_off);
+
+			p1 = ao + 18 + i;  /* wm2 for cbcr */
+			*p1 = (regp1->paddr + regp1->info.planar2_off);
+			regp1++;
+		}
+		for (i = 0; i < 2; i++) {
+			p2 = ao + 30 + i;    /* wm4 for y  */
+			*p2 = (regp2->paddr + regp2->info.planar0_off);
+
+			p2 = ao + 36 + i;  /* wm5 for cbcr */
+			*p2 = (regp2->paddr + regp2->info.planar1_off);
+			regp2++;
+		}
+		for (i = 2; i < ad->bufnum1; i++) {
+			ret = vfe31_add_free_buf(outp1, regp1);
+			if (ret < 0)
+				return ret;
+			regp1++;
+		}
+		for (i = 2; i < ad->bufnum2; i++) {
+			ret = vfe31_add_free_buf(outp2, regp2);
+			if (ret < 0)
+				return ret;
+			regp2++;
+		}
+	}
+		break;
+
 	case CAMIF_TO_AXI_VIA_OUTPUT_2: {  /* use wm0 only */
 		if (ad->bufnum2 < 1)
 			return -EINVAL;
@@ -887,7 +1013,7 @@
 		regp1 = &(ad->region[ad->bufnum1]);
 		vfe31_ctrl->outpath.output_mode |= VFE31_OUTPUT_MODE_S;
 		p1 = ao + 6;    /* wm0 for y  */
-		*p1 = (regp1->paddr + regp1->info.y_off);
+		*p1 = (regp1->paddr + regp1->info.planar0_off);
 		if (p_sync->stereocam_enabled)
 			p_sync->stereo_state = STEREO_RAW_SNAP_IDLE;
 	}
@@ -1193,6 +1319,11 @@
 			irq_comp_mask |=
 				((0x1 << (vfe31_ctrl->outpath.out0.ch0)) |
 				(0x1 << (vfe31_ctrl->outpath.out0.ch1)));
+		} else if (vfe31_ctrl->outpath.output_mode &
+				VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+			irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+				0x1 << vfe31_ctrl->outpath.out0.ch1 |
+				0x1 << vfe31_ctrl->outpath.out0.ch2);
 		}
 		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_T) {
 			irq_comp_mask |=
@@ -1209,6 +1340,14 @@
 				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
 			msm_io_w(1, vfe31_ctrl->vfebase +
 				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		} else if (vfe31_ctrl->outpath.output_mode &
+				VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+			msm_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+			msm_io_w(1, vfe31_ctrl->vfebase +
+				vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
 		}
 		if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_T) {
 			msm_io_w(1, vfe31_ctrl->vfebase +
@@ -1302,12 +1441,22 @@
 	if ((vfe31_ctrl->operation_mode != VFE_MODE_OF_OPERATION_CONTINUOUS) &&
 		(vfe31_ctrl->operation_mode != VFE_MODE_OF_OPERATION_VIDEO))
 		return 0;
-	irq_comp_mask	=
+	irq_comp_mask =
 		msm_io_r(vfe31_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 
 	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_PT) {
 		irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
 			0x1 << vfe31_ctrl->outpath.out0.ch1);
+			if (vfe31_ctrl->outpath.out0.ch2 >= 0)
+				irq_comp_mask |=
+					(0x1 << vfe31_ctrl->outpath.out0.ch0 |
+					0x1 << vfe31_ctrl->outpath.out0.ch1 |
+					0x1 << vfe31_ctrl->outpath.out0.ch2);
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+			irq_comp_mask |= (0x1 << vfe31_ctrl->outpath.out0.ch0 |
+				0x1 << vfe31_ctrl->outpath.out0.ch1 |
+				0x1 << vfe31_ctrl->outpath.out0.ch2);
 	}
 
 	if (vfe31_ctrl->outpath.output_mode & VFE31_OUTPUT_MODE_V) {
@@ -1323,7 +1472,19 @@
 			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
 		msm_io_w(1, vfe31_ctrl->vfebase +
 			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		if (vfe31_ctrl->outpath.out0.ch2 >= 0)
+			msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
+	} else if (vfe31_ctrl->outpath.output_mode &
+		VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch0]);
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch1]);
+		msm_io_w(1, vfe31_ctrl->vfebase +
+			vfe31_AXI_WM_CFG[vfe31_ctrl->outpath.out0.ch2]);
 	}
+
 	if (p_sync->stereocam_enabled)
 		msm_camio_set_perf_lvl(S_STEREO_VIDEO);
 	else
@@ -2240,7 +2401,8 @@
 			break;
 		}
 
-		ret = vfe31_add_free_buf2(outch, p, b->y_off, b->cbcr_off);
+		ret = vfe31_add_free_buf2(outch, p, b->planar0_off,
+			b->planar1_off, b->planar2_off);
 		if (ret < 0)
 			return ret;
 		break;
@@ -2267,7 +2429,8 @@
 		} else
 			return -EFAULT;
 
-		ret = vfe31_add_free_buf2(outch, p, b->y_off, b->cbcr_off);
+		ret = vfe31_add_free_buf2(outch, p, b->planar0_off,
+			b->planar1_off,	b->planar2_off);
 		if (ret < 0)
 			return ret;
 		break;
@@ -2403,6 +2566,32 @@
 	}
 		break;
 
+	case CMD_AXI_CFG_ZSL_ALL_CHNLS: {
+		struct axidata *axid;
+		uint32_t *axio;
+		CDBG("%s, CMD_AXI_CFG_ZSL\n", __func__);
+		axid = data;
+		if (!axid)
+			return -EFAULT;
+		axio =
+			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_ZSL_ALL_CHNLS, axid, axio);
+		kfree(axio);
+	}
+		break;
+
 	case CMD_AXI_CFG_VIDEO: {
 		struct axidata *axid;
 		uint32_t *axio = NULL;
@@ -2431,6 +2620,34 @@
 		break;
 	}
 
+	case CMD_AXI_CFG_VIDEO_ALL_CHNLS: {
+		struct axidata *axid;
+		uint32_t *axio = NULL;
+		axid = data;
+		if (!axid) {
+			rc = -EFAULT;
+			break;
+		}
+
+		axio =
+			kmalloc(vfe31_cmd[V31_AXI_OUT_CFG].length,
+				GFP_ATOMIC);
+		if (!axio) {
+			rc = -ENOMEM;
+			break;
+		}
+
+		if (copy_from_user(axio, (void __user *)(vfecmd.value),
+				vfe31_cmd[V31_AXI_OUT_CFG].length)) {
+			kfree(axio);
+			rc = -EFAULT;
+			break;
+		}
+		vfe31_config_axi(OUTPUT_VIDEO_ALL_CHNLS, axid, axio);
+		kfree(axio);
+		break;
+	}
+
 	default:
 		break;
 	}
@@ -2804,7 +3021,7 @@
 
 static void vfe31_process_output_path_irq_0(uint32_t ping_pong)
 {
-	uint32_t pyaddr, pcbcraddr;
+	uint32_t p0_addr, p1_addr, p2_addr;
 #ifdef CONFIG_MSM_CAMERA_V4L2
 	uint32_t pyaddr_ping, pcbcraddr_ping, pyaddr_pong, pcbcraddr_pong;
 #endif
@@ -2816,26 +3033,37 @@
 
 	if (free_buf) {
 		/* Y channel */
-		pyaddr = vfe31_get_ch_addr(ping_pong,
+		p0_addr = vfe31_get_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out0.ch0);
 		/* Chroma channel */
-		pcbcraddr = vfe31_get_ch_addr(ping_pong,
+		p1_addr = vfe31_get_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out0.ch1);
-
-		CDBG("output path 0, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-			 pyaddr, pcbcraddr);
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_P_ALL_CHNLS) {
+			p2_addr = vfe31_get_ch_addr(ping_pong,
+				vfe31_ctrl->outpath.out0.ch2);
+		} else {
+			p2_addr = p0_addr;
+		}
+		CDBG("Output path 0, p0_addr = 0x%x, p1_addr = 0x%x,"
+			 "p2_addr = 0x%x\n", p0_addr, p1_addr, p2_addr);
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out0.ch0,
-			free_buf->paddr + free_buf->y_off);
+			free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out0.ch1,
-			free_buf->paddr + free_buf->cbcr_off);
-
-		kfree(free_buf);
-		/* if continuous mode, for display. (preview) */
-		vfe_send_outmsg(MSG_ID_OUTPUT_P, pyaddr, pcbcraddr);
+			free_buf->paddr + free_buf->planar1_off);
+		if (vfe31_ctrl->outpath.output_mode &
+			VFE31_OUTPUT_MODE_P_ALL_CHNLS)
+			vfe31_put_ch_addr(ping_pong,
+				vfe31_ctrl->outpath.out0.ch2,
+			free_buf->paddr + free_buf->planar2_off);
+			kfree(free_buf);
+			/* if continuous mode, for display. (preview) */
+			vfe_send_outmsg(MSG_ID_OUTPUT_P,  p0_addr, p1_addr,
+				p2_addr);
 	} else {
 		vfe31_ctrl->outpath.out0.frame_drop_cnt++;
 		pr_warning("path_irq_0 - no free buffer!\n");
@@ -2880,54 +3108,54 @@
 
 static void vfe31_process_snapshot_frame(uint32_t ping_pong)
 {
-	uint32_t pyaddr, pcbcraddr;
+	uint32_t p0_addr, p1_addr;
 	struct vfe31_free_buf *free_buf = NULL;
 	/* Y channel- Main Image */
-	pyaddr = vfe31_get_ch_addr(ping_pong,
+	p0_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out1.ch0);
 	/* Chroma channel - TN Image */
-	pcbcraddr = vfe31_get_ch_addr(ping_pong,
+	p1_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out1.ch1);
 
 	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out1);
-	CDBG("%s: snapshot main, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		__func__, pyaddr, pcbcraddr);
+	CDBG("%s: snapshot main, p0_addr = 0x%x, p1_addr = 0x%x\n",
+		__func__, p0_addr, p1_addr);
 	if (free_buf) {
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out1.ch0,
-			free_buf->paddr + free_buf->y_off);
+			free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out1.ch1,
-			free_buf->paddr + free_buf->cbcr_off);
+			free_buf->paddr + free_buf->planar1_off);
 		kfree(free_buf);
 	}
-	vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr);
+	vfe_send_outmsg(MSG_ID_OUTPUT_S, p0_addr, p1_addr, p0_addr);
 
 	/* Y channel- TN Image */
-	pyaddr = vfe31_get_ch_addr(ping_pong,
+	p0_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out0.ch0);
 	/* Chroma channel - TN Image */
-	pcbcraddr = vfe31_get_ch_addr(ping_pong,
+	p1_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out0.ch1);
 
 	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out0);
-	CDBG("%s: snapshot TN, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		__func__, pyaddr, pcbcraddr);
+	CDBG("%s: snapshot TN, p0_addr = 0x%x, p1_addr = 0x%x\n",
+		__func__, p0_addr, p1_addr);
 	if (free_buf) {
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out0.ch0,
-			free_buf->paddr + free_buf->y_off);
+			free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out0.ch1,
-			free_buf->paddr + free_buf->cbcr_off);
+			free_buf->paddr + free_buf->planar1_off);
 		kfree(free_buf);
 	}
 
-	vfe_send_outmsg(MSG_ID_OUTPUT_T, pyaddr, pcbcraddr);
+	vfe_send_outmsg(MSG_ID_OUTPUT_T, p0_addr, p1_addr, p0_addr);
 
 	/* in snapshot mode if done then send
 		snapshot done message */
@@ -2964,14 +3192,14 @@
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out1.ch0,
-			free_buf->paddr + free_buf->y_off);
+			free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out1.ch1,
-			free_buf->paddr + free_buf->cbcr_off);
+			free_buf->paddr + free_buf->planar1_off);
 		kfree(free_buf);
 	}
-	 vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr);
+	 vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr, 0);
 
 	/* in snapshot mode if done then send
 		snapshot done message */
@@ -2986,54 +3214,54 @@
 }
 static void vfe31_process_zsl_frame(uint32_t ping_pong)
 {
-	uint32_t pyaddr, pcbcraddr;
+	uint32_t p0_addr, p1_addr;
 	struct vfe31_free_buf *free_buf = NULL;
 	/* Y channel- Main Image */
-	pyaddr = vfe31_get_ch_addr(ping_pong,
+	p0_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out2.ch0);
 	/* Chroma channel - Main Image */
-	pcbcraddr = vfe31_get_ch_addr(ping_pong,
+	p1_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out2.ch1);
 
 	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out2);
 	CDBG("%s: snapshot main, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		__func__, pyaddr, pcbcraddr);
+		__func__, p0_addr, p1_addr);
 	if (free_buf) {
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out2.ch0,
-			free_buf->paddr + free_buf->y_off);
+			free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out2.ch1,
-			free_buf->paddr + free_buf->cbcr_off);
+			free_buf->paddr + free_buf->planar1_off);
 		kfree(free_buf);
 	}
-	 vfe_send_outmsg(MSG_ID_OUTPUT_S, pyaddr, pcbcraddr);
+	 vfe_send_outmsg(MSG_ID_OUTPUT_S, p0_addr, p1_addr, p0_addr);
 
 	/* Y channel- TN Image */
-	pyaddr = vfe31_get_ch_addr(ping_pong,
+	p0_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out1.ch0);
 	/* Chroma channel - TN Image */
-	pcbcraddr = vfe31_get_ch_addr(ping_pong,
+	p1_addr = vfe31_get_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out1.ch1);
 
 	free_buf = vfe31_get_free_buf(&vfe31_ctrl->outpath.out1);
 	CDBG("%s: snapshot TN, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		__func__, pyaddr, pcbcraddr);
+		__func__, p0_addr, p1_addr);
 	if (free_buf) {
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out1.ch0,
-			free_buf->paddr + free_buf->y_off);
+			free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out1.ch1,
-			free_buf->paddr + free_buf->cbcr_off);
+			free_buf->paddr + free_buf->planar1_off);
 		kfree(free_buf);
 	}
 
-	vfe_send_outmsg(MSG_ID_OUTPUT_T, pyaddr, pcbcraddr);
+	vfe_send_outmsg(MSG_ID_OUTPUT_T, p0_addr, p1_addr, p0_addr);
 }
 
 static void vfe31_process_output_path_irq_1(uint32_t ping_pong)
@@ -3105,7 +3333,7 @@
 
 static void vfe31_process_output_path_irq_2(uint32_t ping_pong)
 {
-	uint32_t pyaddr, pcbcraddr;
+	uint32_t p0_addr, p1_addr, p2_addr;
 	struct vfe31_free_buf *free_buf = NULL;
 
 #ifdef CONFIG_MSM_CAMERA_V4L2
@@ -3135,25 +3363,25 @@
 
 	if (free_buf) {
 		/* Y channel */
-		pyaddr = vfe31_get_ch_addr(ping_pong,
+		p0_addr = vfe31_get_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out2.ch0);
 		/* Chroma channel */
-		pcbcraddr = vfe31_get_ch_addr(ping_pong,
+		p1_addr = vfe31_get_ch_addr(ping_pong,
 			vfe31_ctrl->outpath.out2.ch1);
-
+		p2_addr = p0_addr;
 		CDBG("video output, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-			pyaddr, pcbcraddr);
+			p0_addr, p1_addr);
 
 		/* Y channel */
 		vfe31_put_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out2.ch0,
-		free_buf->paddr + free_buf->y_off);
+		free_buf->paddr + free_buf->planar0_off);
 		/* Chroma channel */
 		vfe31_put_ch_addr(ping_pong,
 		vfe31_ctrl->outpath.out2.ch1,
-		free_buf->paddr + free_buf->cbcr_off);
+		free_buf->paddr + free_buf->planar1_off);
 		kfree(free_buf);
-		vfe_send_outmsg(MSG_ID_OUTPUT_V, pyaddr, pcbcraddr);
+		vfe_send_outmsg(MSG_ID_OUTPUT_V, p0_addr, p1_addr, p2_addr);
 	} else {
 		vfe31_ctrl->outpath.out2.frame_drop_cnt++;
 		pr_warning("path_irq_2 - no free buffer!\n");
diff --git a/drivers/media/video/msm/msm_vfe31.h b/drivers/media/video/msm/msm_vfe31.h
index c47c7de..d1df2dd 100644
--- a/drivers/media/video/msm/msm_vfe31.h
+++ b/drivers/media/video/msm/msm_vfe31.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -842,8 +842,9 @@
 
 struct vfe_msg_output {
 	uint8_t   output_id;
-	uint32_t  yBuffer;
-	uint32_t  cbcrBuffer;
+	uint32_t  p0_addr;
+	uint32_t  p1_addr;
+	uint32_t  p2_addr;
 	struct vfe_frame_bpc_info bpcInfo;
 	struct vfe_frame_asf_info asfInfo;
 	uint32_t  frameCounter;
@@ -878,7 +879,9 @@
 struct vfe31_free_buf {
 	struct list_head node;
 	uint32_t paddr;
-	uint32_t y_off;
+	uint32_t planar0_off;
+	uint32_t planar1_off;
+	uint32_t planar2_off;
 	uint32_t cbcr_off;
 };
 
diff --git a/drivers/media/video/msm/msm_vfe7x.c b/drivers/media/video/msm/msm_vfe7x.c
index 316aacf..d74bebc 100644
--- a/drivers/media/video/msm/msm_vfe7x.c
+++ b/drivers/media/video/msm/msm_vfe7x.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -72,14 +72,14 @@
 {
 	switch (type) {
 	case VFE_MSG_OUTPUT_P: {
-		pinfo->y_phy = ((struct vfe_endframe *)data)->y_address;
-		pinfo->cbcr_phy =
+		pinfo->p0_phy = ((struct vfe_endframe *)data)->y_address;
+		pinfo->p1_phy =
 			((struct vfe_endframe *)data)->cbcr_address;
-
+		pinfo->p2_phy = pinfo->p0_phy;
 		pinfo->output_id = OUTPUT_TYPE_P;
 
 		CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
-				 pinfo->y_phy, pinfo->cbcr_phy);
+				 pinfo->p0_phy, pinfo->p1_phy);
 
 		((struct vfe_frame_extra *)extdata)->bl_evencol =
 		((struct vfe_endframe *)data)->blacklevelevencolumn;
@@ -99,20 +99,22 @@
 		break;
 
 	case VFE_MSG_OUTPUT_S: {
-		pinfo->y_phy = paddr_s_y;
-		pinfo->cbcr_phy = paddr_s_cbcr;
+		pinfo->p0_phy = paddr_s_y;
+		pinfo->p1_phy = paddr_s_cbcr;
+		pinfo->p2_phy = pinfo->p0_phy;
 		pinfo->output_id = OUTPUT_TYPE_S;
 		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
-					pinfo->y_phy, pinfo->cbcr_phy);
+					pinfo->p0_phy, pinfo->p1_phy);
 	}
 		break;
 
 	case VFE_MSG_OUTPUT_T: {
-		pinfo->y_phy = paddr_t_y;
-		pinfo->cbcr_phy = paddr_t_cbcr;
+		pinfo->p0_phy = paddr_t_y;
+		pinfo->p1_phy = paddr_t_cbcr;
+		pinfo->p2_phy = pinfo->p0_phy;
 		pinfo->output_id = OUTPUT_TYPE_T;
 		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
-					pinfo->y_phy, pinfo->cbcr_phy);
+					pinfo->p0_phy, pinfo->p1_phy);
 	}
 		break;
 
@@ -372,19 +374,19 @@
 
 		CDBG("bufnum1 = %d\n", ad->bufnum1);
 		if (mode == OUTPUT_1_AND_2) {
-			paddr_t_y = regptr->paddr + regptr->info.y_off;
-			paddr_t_cbcr = regptr->paddr +  regptr->info.cbcr_off;
+			paddr_t_y = regptr->paddr + regptr->info.planar0_off;
+			paddr_t_cbcr = regptr->paddr + regptr->info.planar1_off;
 		}
 
 		CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-			regptr->paddr, regptr->info.y_off,
-			regptr->info.cbcr_off);
+			regptr->paddr, regptr->info.planar0_off,
+			regptr->info.planar1_off);
 
 		bptr = &ao->output1buffer1_y_phy;
 		for (cnt = 0; cnt < ad->bufnum1; cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 
 			bptr++;
 			regptr++;
@@ -392,9 +394,9 @@
 
 		regptr--;
 		for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 			bptr++;
 		}
 	} /* if OUTPUT1 or Both */
@@ -403,16 +405,17 @@
 		regptr = &(ad->region[ad->bufnum1]);
 
 		CDBG("bufnum2 = %d\n", ad->bufnum2);
-		paddr_s_y = regptr->paddr +  regptr->info.y_off;
-		paddr_s_cbcr = regptr->paddr +  regptr->info.cbcr_off;
+		paddr_s_y = regptr->paddr +  regptr->info.planar0_off;
+		paddr_s_cbcr = regptr->paddr +  regptr->info.planar1_off;
 		CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-		     regptr->paddr, regptr->info.y_off, regptr->info.cbcr_off);
+			regptr->paddr, regptr->info.planar0_off,
+			regptr->info.planar1_off);
 
 		bptr = &ao->output2buffer1_y_phy;
 		for (cnt = 0; cnt < ad->bufnum2; cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 
 			bptr++;
 			regptr++;
@@ -420,9 +423,9 @@
 
 		regptr--;
 		for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 			bptr++;
 		}
 	}
@@ -584,10 +587,10 @@
 		fack.header = VFE_FRAME_ACK;
 
 		fack.output2newybufferaddress =
-			(void *)(p + b->y_off);
+			(void *)(p + b->planar0_off);
 
 		fack.output2newcbcrbufferaddress =
-			(void *)(p + b->cbcr_off);
+			(void *)(p + b->planar1_off);
 
 		vfecmd->queue = QDSP_CMDQUEUE;
 		vfecmd->length = sizeof(struct vfe_outputack);
diff --git a/drivers/media/video/msm/msm_vfe7x27a.c b/drivers/media/video/msm/msm_vfe7x27a.c
index 9f7dff7..337085d 100644
--- a/drivers/media/video/msm/msm_vfe7x27a.c
+++ b/drivers/media/video/msm/msm_vfe7x27a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -72,14 +72,14 @@
 {
 	switch (type) {
 	case VFE_MSG_OUTPUT_P: {
-		pinfo->y_phy = ((struct vfe_endframe *)data)->y_address;
-		pinfo->cbcr_phy =
+		pinfo->p0_phy = ((struct vfe_endframe *)data)->y_address;
+		pinfo->p1_phy =
 			((struct vfe_endframe *)data)->cbcr_address;
-
+		pinfo->p2_phy = pinfo->p0_phy;
 		pinfo->output_id = OUTPUT_TYPE_P;
 
 		CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
-				 pinfo->y_phy, pinfo->cbcr_phy);
+				 pinfo->p0_phy, pinfo->p1_phy);
 
 		memcpy(((struct vfe_frame_extra *)extdata),
 			&((struct vfe_endframe *)data)->extra,
@@ -92,19 +92,21 @@
 	}
 		break;
 	case VFE_MSG_OUTPUT_S: {
-		pinfo->y_phy = paddr_s_y;
-		pinfo->cbcr_phy = paddr_s_cbcr;
+		pinfo->p0_phy = paddr_s_y;
+		pinfo->p1_phy = paddr_s_cbcr;
+		pinfo->p2_phy = pinfo->p0_phy;
 		pinfo->output_id = OUTPUT_TYPE_S;
 		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
-					pinfo->y_phy, pinfo->cbcr_phy);
+					pinfo->p0_phy, pinfo->p1_phy);
 	}
 		break;
 	case VFE_MSG_OUTPUT_T: {
-		pinfo->y_phy = paddr_t_y;
-		pinfo->cbcr_phy = paddr_t_cbcr;
+		pinfo->p0_phy = paddr_t_y;
+		pinfo->p1_phy = paddr_t_cbcr;
+		pinfo->p2_phy = pinfo->p0_phy;
 		pinfo->output_id = OUTPUT_TYPE_T;
 		CDBG("vfe_7x_convert: y_phy = 0x%x cbcr_phy = 0x%x\n",
-					pinfo->y_phy, pinfo->cbcr_phy);
+					pinfo->p0_phy, pinfo->p1_phy);
 	}
 		break;
 	case VFE_MSG_STATS_AF:
@@ -354,19 +356,20 @@
 
 		CDBG("bufnum1 = %d\n", ad->bufnum1);
 		if (mode == OUTPUT_1_AND_2) {
-			paddr_t_y = regptr->paddr + regptr->info.y_off;
-			paddr_t_cbcr = regptr->paddr +  regptr->info.cbcr_off;
+			paddr_t_y = regptr->paddr + regptr->info.planar0_off;
+			paddr_t_cbcr = regptr->paddr +
+			regptr->info.planar1_off;
 		}
 
 		CDBG("config_axi1: O1, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-			regptr->paddr, regptr->info.y_off,
-			regptr->info.cbcr_off);
+			regptr->paddr, regptr->info.planar0_off,
+			regptr->info.planar1_off);
 
 		bptr = &ao->output1buffer1_y_phy;
 		for (cnt = 0; cnt < ad->bufnum1; cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 
 			bptr++;
 			regptr++;
@@ -374,9 +377,9 @@
 
 		regptr--;
 		for (cnt = 0; cnt < (8 - ad->bufnum1); cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 			bptr++;
 		}
 	}
@@ -385,17 +388,18 @@
 		regptr = &(ad->region[ad->bufnum1]);
 
 		CDBG("bufnum2 = %d\n", ad->bufnum2);
-		paddr_s_y = regptr->paddr +  regptr->info.y_off;
-		paddr_s_cbcr = regptr->paddr +  regptr->info.cbcr_off;
+		paddr_s_y = regptr->paddr +  regptr->info.planar0_off;
+		paddr_s_cbcr = regptr->paddr +  regptr->info.planar1_off;
 
 		CDBG("config_axi2: O2, phy = 0x%lx, y_off = %d, cbcr_off =%d\n",
-		     regptr->paddr, regptr->info.y_off, regptr->info.cbcr_off);
+			regptr->paddr, regptr->info.planar0_off,
+			regptr->info.planar1_off);
 
 		bptr = &ao->output2buffer1_y_phy;
 		for (cnt = 0; cnt < ad->bufnum2; cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 
 			bptr++;
 			regptr++;
@@ -403,9 +407,9 @@
 
 		regptr--;
 		for (cnt = 0; cnt < (8 - ad->bufnum2); cnt++) {
-			*bptr = regptr->paddr + regptr->info.y_off;
+			*bptr = regptr->paddr + regptr->info.planar0_off;
 			bptr++;
-			*bptr = regptr->paddr + regptr->info.cbcr_off;
+			*bptr = regptr->paddr + regptr->info.planar1_off;
 			bptr++;
 		}
 	}
@@ -563,10 +567,10 @@
 		fack.header = VFE_FRAME_ACK;
 
 		fack.output2newybufferaddress =
-			(void *)(p + b->y_off);
+			(void *)(p + b->planar0_off);
 
 		fack.output2newcbcrbufferaddress =
-			(void *)(p + b->cbcr_off);
+			(void *)(p + b->planar1_off);
 
 		vfecmd->queue = QDSP_CMDQUEUE;
 		vfecmd->length = sizeof(struct vfe_outputack);
diff --git a/drivers/media/video/msm/msm_vfe8x.c b/drivers/media/video/msm/msm_vfe8x.c
index 0bf1785..a99c6f1 100644
--- a/drivers/media/video/msm/msm_vfe8x.c
+++ b/drivers/media/video/msm/msm_vfe8x.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009, 2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -122,10 +122,10 @@
 
 			for (j = 0; j < ao->output1.fragmentCount; j++) {
 
-				*p1 = regptr->paddr + regptr->info.y_off;
+				*p1 = regptr->paddr + regptr->info.planar0_off;
 				p1++;
 
-				*p2 = regptr->paddr + regptr->info.cbcr_off;
+				*p2 = regptr->paddr + regptr->info.planar1_off;
 				p2++;
 			}
 			regptr++;
@@ -144,15 +144,16 @@
 
 			CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, "\
 			     "cbcr_off = %d\n", regptr->paddr,
-			     regptr->info.y_off, regptr->info.cbcr_off);
+				regptr->info.planar0_off,
+				regptr->info.planar1_off);
 
 			for (j = 0; j < ao->output2.fragmentCount; j++) {
 
-				*p1 = regptr->paddr + regptr->info.y_off;
+				*p1 = regptr->paddr + regptr->info.planar0_off;
 				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
 				p1++;
 
-				*p2 = regptr->paddr + regptr->info.cbcr_off;
+				*p2 = regptr->paddr + regptr->info.planar1_off;
 				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
 				p2++;
 			}
@@ -174,15 +175,15 @@
 
 		CDBG("config_axi: O1, phy = 0x%lx, y_off = %d, "\
 			 "cbcr_off = %d\n", regptr->paddr,
-			 regptr->info.y_off, regptr->info.cbcr_off);
+			 regptr->info.planar0_off, regptr->info.planar1_off);
 
 			for (j = 0; j < ao->output1.fragmentCount; j++) {
 
-				*p1 = regptr->paddr + regptr->info.y_off;
+				*p1 = regptr->paddr + regptr->info.planar0_off;
 				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
 				p1++;
 
-				*p2 = regptr->paddr + regptr->info.cbcr_off;
+				*p2 = regptr->paddr + regptr->info.planar1_off;
 				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
 				p2++;
 			}
@@ -194,15 +195,15 @@
 
 		CDBG("config_axi: O2, phy = 0x%lx, y_off = %d, "\
 			 "cbcr_off = %d\n", regptr1->paddr,
-			 regptr1->info.y_off, regptr1->info.cbcr_off);
+			 regptr1->info.planar0_off, regptr1->info.planar1_off);
 
 			for (j = 0; j < ao->output2.fragmentCount; j++) {
-
-				*p1 = regptr1->paddr + regptr1->info.y_off;
+				*p1 = regptr1->paddr +
+					regptr1->info.planar0_off;
 				CDBG("vfe_config_axi: p1 = 0x%x\n", *p1);
 				p1++;
-
-				*p2 = regptr1->paddr + regptr1->info.cbcr_off;
+				*p2 = regptr1->paddr +
+					r1->info.planar1_off;
 				CDBG("vfe_config_axi: p2 = 0x%x\n", *p2);
 				p2++;
 			}
@@ -689,9 +690,9 @@
 		b = (struct msm_frame *)(cmd->value);
 		p = *(unsigned long *)data;
 
-			fack.ybufaddr[0] = (uint32_t) (p + b->y_off);
+			fack.ybufaddr[0] = (uint32_t) (p + b->planar0_off);
 
-			fack.chromabufaddr[0] = (uint32_t) (p + b->cbcr_off);
+			fack.chromabufaddr[0] = (uint32_t) (p + b->planar1_off);
 
 		if (b->path == OUTPUT_TYPE_P)
 			vfe_output_p_ack(&fack);
diff --git a/drivers/media/video/msm/msm_vfe8x_proc.c b/drivers/media/video/msm/msm_vfe8x_proc.c
index 9764557..055b244 100644
--- a/drivers/media/video/msm/msm_vfe8x_proc.c
+++ b/drivers/media/video/msm/msm_vfe8x_proc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -608,11 +608,12 @@
 	switch (type) {
 	case VFE_MSG_OUTPUT_P:
 	case VFE_MSG_OUTPUT_V:{
-		pinfo->y_phy =
+		pinfo->planar0_off =
 			((struct vfe_message *)data)->_u.msgOutput2.yBuffer;
-		pinfo->cbcr_phy =
+		pinfo->planar1_off =
 			((struct vfe_message *)data)->_u.msgOutput2.
 			cbcrBuffer;
+		pinfo->planar2_off = pinfo->planar0_off;
 		ctrl->extdata.bpcInfo =
 			((struct vfe_message *)data)->_u.msgOutput2.bpcInfo;
 		ctrl->extdata.asfInfo =
diff --git a/drivers/media/video/msm/msm_vpe1.c b/drivers/media/video/msm/msm_vpe1.c
index 891816f..5f128e1 100644
--- a/drivers/media/video/msm/msm_vpe1.c
+++ b/drivers/media/video/msm/msm_vpe1.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -709,15 +709,15 @@
 	return 1;
 }
 
-void msm_send_frame_to_vpe(uint32_t pyaddr, uint32_t pcbcraddr,
+void msm_send_frame_to_vpe(uint32_t p0_phy_add, uint32_t p1_phy_add,
 		struct timespec *ts, int output_type)
 {
 	uint32_t temp_pyaddr = 0, temp_pcbcraddr = 0;
 
-	CDBG("vpe input, pyaddr = 0x%x, pcbcraddr = 0x%x\n",
-		pyaddr, pcbcraddr);
-	msm_io_w(pyaddr, vpe_device->vpebase + VPE_SRCP0_ADDR_OFFSET);
-	msm_io_w(pcbcraddr, vpe_device->vpebase + VPE_SRCP1_ADDR_OFFSET);
+	CDBG("vpe input, p0_phy_add = 0x%x, p1_phy_add = 0x%x\n",
+		p0_phy_add, p1_phy_add);
+	msm_io_w(p0_phy_add, vpe_device->vpebase + VPE_SRCP0_ADDR_OFFSET);
+	msm_io_w(p1_phy_add, vpe_device->vpebase + VPE_SRCP1_ADDR_OFFSET);
 
 	if (vpe_ctrl->state == VPE_STATE_ACTIVE)
 		CDBG(" =====VPE is busy!!!  Wrong!========\n");
@@ -881,7 +881,7 @@
 		vpe_update_scaler_with_dis(&(vpe_buf->vpe_crop),
 					&(vpe_ctrl->dis_offset));
 
-		msm_send_frame_to_vpe(vpe_buf->y_phy, vpe_buf->cbcr_phy,
+		msm_send_frame_to_vpe(vpe_buf->p0_phy, vpe_buf->p1_phy,
 						&(vpe_buf->ts), OUTPUT_TYPE_V);
 
 		if (!qcmd || !atomic_read(&qcmd->on_heap)) {
@@ -919,10 +919,10 @@
 
 	CDBG("In vpe_addr_convert output_id = %d\n", pinfo->output_id);
 
-	pinfo->y_phy =
-		((struct vpe_message *)data)->_u.msgOut.yBuffer;
-	pinfo->cbcr_phy =
-		((struct vpe_message *)data)->_u.msgOut.cbcrBuffer;
+	pinfo->p0_phy =
+		((struct vpe_message *)data)->_u.msgOut.p0_Buffer;
+	pinfo->p1_phy =
+		((struct vpe_message *)data)->_u.msgOut.p1_Buffer;
 	*ext  = vpe_ctrl->extdata;
 	*elen = vpe_ctrl->extlen;
 }
@@ -987,10 +987,10 @@
 
 	regp1 = &(ad->region[0]);
 	/* for video  Y address */
-	p1 = (regp1->paddr + regp1->info.y_off);
+	p1 = (regp1->paddr + regp1->info.planar0_off);
 	msm_io_w(p1, vpe_device->vpebase + VPE_OUTP0_ADDR_OFFSET);
 	/* for video  CbCr address */
-	p1 = (regp1->paddr + regp1->info.cbcr_off);
+	p1 = (regp1->paddr + regp1->info.planar1_off);
 	msm_io_w(p1, vpe_device->vpebase + VPE_OUTP1_ADDR_OFFSET);
 
 	return 0;
@@ -1048,8 +1048,8 @@
 	vpe_ctrl->frame_pack = frame_pack;
 	vpe_ctrl->output_type = output_id;
 
-	input_stride = (st_half.buf_cbcr_stride * (1<<16)) +
-		st_half.buf_y_stride;
+	input_stride = (st_half.buf_p1_stride * (1<<16)) +
+		st_half.buf_p0_stride;
 
 	msm_io_w(input_stride, vpe_device->vpebase + VPE_SRC_YSTRIDE1_OFFSET);
 
@@ -1059,15 +1059,16 @@
 	msm_send_frame_to_vpe(pyaddr, pcbcraddr, ts, output_id);
 }
 
-static void vpe_send_outmsg(uint8_t msgid, uint32_t pyaddr,
-	uint32_t pcbcraddr)
+static void vpe_send_outmsg(uint8_t msgid, uint32_t p0_addr,
+	uint32_t p1_addr, uint32_t p2_addr)
 {
 	struct vpe_message msg;
 	uint8_t outid;
 	msg._d = outid = msgid;
 	msg._u.msgOut.output_id   = msgid;
-	msg._u.msgOut.yBuffer     = pyaddr;
-	msg._u.msgOut.cbcrBuffer  = pcbcraddr;
+	msg._u.msgOut.p0_Buffer = p0_addr;
+	msg._u.msgOut.p1_Buffer = p1_addr;
+	msg._u.msgOut.p2_Buffer = p2_addr;
 	vpe_proc_ops(outid, &msg, sizeof(struct vpe_message));
 	return;
 }
@@ -1203,10 +1204,11 @@
 		if (vpe_ctrl->output_type == OUTPUT_TYPE_ST_R) {
 			CDBG("vpe send out R msg.\n");
 			vpe_send_outmsg(MSG_ID_VPE_OUTPUT_ST_R, pyaddr,
-				pcbcraddr);
+				pcbcraddr, pyaddr);
 		} else if (vpe_ctrl->output_type == OUTPUT_TYPE_V) {
 			CDBG("vpe send out V msg.\n");
-			vpe_send_outmsg(MSG_ID_VPE_OUTPUT_V, pyaddr, pcbcraddr);
+			vpe_send_outmsg(MSG_ID_VPE_OUTPUT_V, pyaddr,
+				pcbcraddr, pyaddr);
 		}
 
 		vpe_ctrl->output_type = 0;
diff --git a/drivers/media/video/msm/msm_vpe1.h b/drivers/media/video/msm/msm_vpe1.h
index ed7112e..f4d328d 100644
--- a/drivers/media/video/msm/msm_vpe1.h
+++ b/drivers/media/video/msm/msm_vpe1.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -212,8 +212,9 @@
 
 struct vpe_msg_output {
 	uint8_t   output_id;
-	uint32_t  yBuffer;
-	uint32_t  cbcrBuffer;
+	uint32_t  p0_Buffer;
+	uint32_t  p1_Buffer;
+	uint32_t  p2_Buffer;
 	uint32_t  frameCounter;
 };
 
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 423a849..a984943 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -396,11 +396,11 @@
 #define CMD_AXI_CFG_ZSL 43
 #define CMD_AXI_CFG_SNAP_VPE 44
 #define CMD_AXI_CFG_SNAP_THUMB_VPE 45
-#define CMD_AXI_CFG_VIDEO_ALL_CHNLS  46
-#define CMD_AXI_CFG_ZSL_ALL_CHNLS  47
-#define CMD_CONFIG_PING_ADDR 48
-#define CMD_CONFIG_PONG_ADDR 49
-#define CMD_CONFIG_FREE_BUF_ADDR 50
+#define CMD_CONFIG_PING_ADDR 46
+#define CMD_CONFIG_PONG_ADDR 47
+#define CMD_CONFIG_FREE_BUF_ADDR 48
+#define CMD_AXI_CFG_ZSL_ALL_CHNLS 49
+#define CMD_AXI_CFG_VIDEO_ALL_CHNLS 50
 
 /* vfe config command: config command(from config thread)*/
 struct msm_vfe_cfg_cmd {
@@ -467,6 +467,9 @@
 	uint32_t len;
 	uint32_t y_off;
 	uint32_t cbcr_off;
+	uint32_t planar0_off;
+	uint32_t planar1_off;
+	uint32_t planar2_off;
 	uint8_t active;
 };
 
@@ -487,8 +490,9 @@
 #define OUTPUT_2_AND_CAMIF_TO_AXI_VIA_OUTPUT_1 6
 #define OUTPUT_1_2_AND_3 7
 #define OUTPUT_ALL_CHNLS 8
-#define OUTPUT_ZSL_ALL_CHNLS 9
-#define LAST_AXI_OUTPUT_MODE_ENUM  OUTPUT_ZSL_ALL_CHNLS
+#define OUTPUT_VIDEO_ALL_CHNLS 9
+#define OUTPUT_ZSL_ALL_CHNLS 10
+#define LAST_AXI_OUTPUT_MODE_ENUM = OUTPUT_ZSL_ALL_CHNLS
 
 #define MSM_FRAME_PREV_1	0
 #define MSM_FRAME_PREV_2	1
@@ -528,6 +532,9 @@
 	uint32_t phy_offset;
 	uint32_t y_off;
 	uint32_t cbcr_off;
+	uint32_t planar0_off;
+	uint32_t planar1_off;
+	uint32_t planar2_off;
 	int fd;
 
 	void *cropinfo;
@@ -557,10 +564,10 @@
 };
 
 struct msm_st_half {
-	uint32_t buf_y_off;
-	uint32_t buf_cbcr_off;
-	uint32_t buf_y_stride;
-	uint32_t buf_cbcr_stride;
+	uint32_t buf_p0_off;
+	uint32_t buf_p1_off;
+	uint32_t buf_p0_stride;
+	uint32_t buf_p1_stride;
 	uint32_t pix_x_off;
 	uint32_t pix_y_off;
 	struct msm_st_crop stCropInfo;