msm-camera: Add 8MP and 1MP sensor support

Add support to mt9e013 and ov9726 sensors for v4l2 camera
architecture

Change-Id: Ie0e12bb0b8f1d80c0aa40800f5578208ca86efcb
Signed-off-by: Sandeep Kodimela <skodimela@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index 7b075cd..ea3a36d 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -33,6 +33,39 @@
 	GPIO_CFG(15, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
 };
 
+static struct gpio s5k4e1_cam_req_gpio[] = {
+	{GPIO_CAM_GP_CAMIF_RESET_N, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct msm_gpio_set_tbl s5k4e1_cam_gpio_set_tbl[] = {
+	{GPIO_CAM_GP_CAMIF_RESET_N, GPIOF_OUT_INIT_LOW, 1000},
+	{GPIO_CAM_GP_CAMIF_RESET_N, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_camera_gpio_conf gpio_conf_s5k4e1 = {
+	.camera_off_table = camera_off_gpio_table,
+	.camera_off_table_size = ARRAY_SIZE(camera_off_gpio_table),
+	.camera_on_table = camera_on_gpio_table,
+	.camera_on_table_size = ARRAY_SIZE(camera_on_gpio_table),
+	.cam_gpio_req_tbl = s5k4e1_cam_req_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(s5k4e1_cam_req_gpio),
+	.cam_gpio_set_tbl = s5k4e1_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(s5k4e1_cam_gpio_set_tbl),
+	.gpio_no_mux = 1,
+};
+
+static struct msm_camera_gpio_conf gpio_conf_mt9e013 = {
+	.camera_off_table = camera_off_gpio_table,
+	.camera_on_table = camera_on_gpio_table,
+	.gpio_no_mux = 1,
+};
+
+static struct msm_camera_gpio_conf gpio_conf_ov9726 = {
+	.camera_off_table = camera_off_gpio_table,
+	.camera_on_table = camera_on_gpio_table,
+	.gpio_no_mux = 1,
+};
+
 #ifdef CONFIG_MSM_CAMERA_FLASH
 static struct msm_camera_sensor_flash_src msm_flash_src = {
 	.flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
@@ -41,111 +74,22 @@
 };
 #endif
 
-static struct regulator_bulk_data regs_camera[] = {
-	{ .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
-	{ .supply = "gp2",   .min_uV = 2850000, .max_uV = 2850000 },
-	{ .supply = "usb2",  .min_uV = 1800000, .max_uV = 1800000 },
+static struct camera_vreg_t msm_cam_vreg[] = {
+	{"msme1", REG_LDO, 1800000, 1800000, 0},
+	{"gp2", REG_LDO, 2850000, 2850000, 0},
+	{"usb2", REG_LDO, 1800000, 1800000, 0},
 };
 
-static void msm_camera_vreg_config(int vreg_en)
-{
-	int rc = vreg_en ?
-		regulator_bulk_enable(ARRAY_SIZE(regs_camera), regs_camera) :
-		regulator_bulk_disable(ARRAY_SIZE(regs_camera), regs_camera);
-
-	if (rc)
-		pr_err("%s: could not %sable regulators: %d\n",
-				__func__, vreg_en ? "en" : "dis", rc);
-}
-
-static int config_gpio_table(uint32_t *table, int len)
-{
-	int rc = 0, i = 0;
-
-	for (i = 0; i < len; i++) {
-		rc = gpio_tlmm_config(table[i], GPIO_CFG_ENABLE);
-		if (rc) {
-			pr_err("%s not able to get gpio\n", __func__);
-			for (i--; i >= 0; i--)
-				gpio_tlmm_config(camera_off_gpio_table[i],
-							GPIO_CFG_ENABLE);
-			break;
-		}
-	}
-	return rc;
-}
-
 static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data;
-/* TODO: static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data; */
-static int config_camera_on_gpios_rear(void)
-{
-	int rc = 0;
-
-	if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
-		msm_camera_vreg_config(1);
-
-	rc = config_gpio_table(camera_on_gpio_table,
-			ARRAY_SIZE(camera_on_gpio_table));
-	if (rc < 0) {
-		pr_err("%s: CAMSENSOR gpio table request"
-		"failed\n", __func__);
-		return rc;
-	}
-
-	return rc;
-}
-
-static void config_camera_off_gpios_rear(void)
-{
-	if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
-		msm_camera_vreg_config(0);
-
-	config_gpio_table(camera_off_gpio_table,
-			ARRAY_SIZE(camera_off_gpio_table));
-}
-
-static int config_camera_on_gpios_front(void)
-{
-	int rc = 0;
-
-	if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
-		msm_camera_vreg_config(1);
-
-	rc = config_gpio_table(camera_on_gpio_table,
-			ARRAY_SIZE(camera_on_gpio_table));
-	if (rc < 0) {
-		pr_err("%s: CAMSENSOR gpio table request"
-			"failed\n", __func__);
-		return rc;
-	}
-
-	return rc;
-}
-
-static void config_camera_off_gpios_front(void)
-{
-	if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa())
-		msm_camera_vreg_config(0);
-
-	config_gpio_table(camera_off_gpio_table,
-			ARRAY_SIZE(camera_off_gpio_table));
-}
 
 struct msm_camera_device_platform_data msm_camera_device_data_csi1 = {
-	.camera_gpio_on  = config_camera_on_gpios_rear,
-	.camera_gpio_off = config_camera_off_gpios_rear,
-	.ioclk.mclk_clk_rate = 24000000,
-	.ioclk.vfe_clk_rate  = 192000000,
 	.csid_core = 1,
 	.is_csic = 1,
 };
 
 struct msm_camera_device_platform_data msm_camera_device_data_csi0 = {
-	.camera_gpio_on  = config_camera_on_gpios_front,
-	.camera_gpio_off = config_camera_off_gpios_front,
-	.ioclk.mclk_clk_rate = 24000000,
-	.ioclk.vfe_clk_rate  = 192000000,
 	.csid_core = 0,
+	.is_csic = 1,
 };
 
 #ifdef CONFIG_DW9712_ACT
@@ -169,10 +113,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_s5k4e1 = {
 	.mount_angle	= 90,
-	.sensor_reset	= GPIO_CAM_GP_CAMIF_RESET_N,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= GPIO_CAM_GP_CAM_PWDN,
-	.vcm_enable	= 1,
+	.cam_vreg = msm_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_cam_vreg),
+	.gpio_conf = &gpio_conf_s5k4e1,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data = {
@@ -198,10 +141,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_mt9e013 = {
 	.mount_angle	= 90,
-	.sensor_reset	= 0,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 1,
-	.vcm_enable	= 0,
+	.cam_vreg = msm_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_cam_vreg),
+	.gpio_conf = &gpio_conf_mt9e013,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_mt9e013_data = {
@@ -256,10 +198,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_ov9726 = {
 	.mount_angle	= 90,
-	.sensor_reset	= GPIO_CAM_GP_CAM1MP_XCLR,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 1,
-	.vcm_enable	= 0,
+	.cam_vreg = msm_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_cam_vreg),
+	.gpio_conf = &gpio_conf_ov9726,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data = {
@@ -276,6 +217,15 @@
 
 static void __init msm7x27a_init_cam(void)
 {
+	if (!(machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
+				|| machine_is_msm7627a_qrd1())) {
+		sensor_board_info_s5k4e1.cam_vreg = NULL;
+		sensor_board_info_s5k4e1.num_vreg = 0;
+		sensor_board_info_mt9e013.cam_vreg = NULL;
+		sensor_board_info_mt9e013.num_vreg = 0;
+		sensor_board_info_ov9726.cam_vreg = NULL;
+		sensor_board_info_ov9726.num_vreg = 0;
+	}
 	platform_device_register(&msm7x27a_device_csic0);
 	platform_device_register(&msm7x27a_device_csic1);
 	platform_device_register(&msm7x27a_device_clkctl);
@@ -939,6 +889,7 @@
 				ARRAY_SIZE(cam_exp_i2c_info));
 }
 
+#ifndef CONFIG_MSM_CAMERA_V4L2
 #define LCD_CAMERA_LDO_2V8 35 /* SKU1&SKU3 2.8V LDO */
 #define SKU3_LCD_CAMERA_LDO_1V8 40 /* SKU3 1.8V LDO */
 
@@ -1033,10 +984,11 @@
 	return rc;
 }
 EXPORT_SYMBOL(lcd_camera_power_onoff);
-
+#endif
 
 void __init msm7627a_camera_init(void)
 {
+#ifndef CONFIG_MSM_CAMERA_V4L2
 	int rc;
 
 	pr_debug("msm7627a_camera_init Entered\n");
@@ -1044,7 +996,6 @@
 	if (machine_is_msm7627a_evb() || machine_is_msm8625_evb())
 		lcd_camera_power_init();
 
-#ifndef CONFIG_MSM_CAMERA_V4L2
 	if (machine_is_msm7627a_qrd1()) {
 		qrd1_camera_gpio_cfg();
 		platform_add_devices(camera_devices_qrd,
@@ -1062,6 +1013,7 @@
 	if (!machine_is_msm7627a_qrd1() || !machine_is_msm7627a_evb()
 					|| !machine_is_msm8625_evb())
 		register_i2c_devices();
+#ifndef CONFIG_MSM_CAMERA_V4L2
 	rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_camera), regs_camera);
 
 	if (rc) {
@@ -1075,6 +1027,7 @@
 		pr_err("%s: could not set voltages: %d\n", __func__, rc);
 		return;
 	}
+#endif
 
 #if defined(CONFIG_MSM_CAMERA_V4L2)
 	msm7x27a_init_cam();
@@ -1091,6 +1044,7 @@
 				ARRAY_SIZE(i2c_camera_devices_evb));
 	} else
 #endif
+		pr_debug("i2c_register_board_info\n");
 		i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
 				i2c_camera_devices,
 				ARRAY_SIZE(i2c_camera_devices));
diff --git a/arch/arm/mach-msm/clock-pcom-lookup.c b/arch/arm/mach-msm/clock-pcom-lookup.c
index c20b7e4..f43a468 100644
--- a/arch/arm/mach-msm/clock-pcom-lookup.c
+++ b/arch/arm/mach-msm/clock-pcom-lookup.c
@@ -317,6 +317,9 @@
 	CLK_LOOKUP("ahb_m_clk",		ahb_m_clk.c,	NULL),
 	CLK_LOOKUP("ahb_s_clk",		ahb_s_clk.c,	NULL),
 	CLK_LOOKUP("cam_m_clk",		cam_m_clk.c,	NULL),
+	CLK_LOOKUP("cam_clk",		cam_m_clk.c,	"0-0036"),
+	CLK_LOOKUP("cam_clk",		cam_m_clk.c,	"0-001b"),
+	CLK_LOOKUP("cam_clk",		cam_m_clk.c,	"0-0010"),
 	CLK_LOOKUP("csi_clk",		csi0_clk.c,	"msm_camera_ov9726.0"),
 	CLK_LOOKUP("csi_pclk",		csi0_p_clk.c,	"msm_camera_ov9726.0"),
 	CLK_LOOKUP("csi_vfe_clk",	csi0_vfe_clk.c,	"msm_camera_ov9726.0"),
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index a87a759..7fa4a07 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -200,6 +200,11 @@
 	uint8_t cam_gpio_req_tbl_size;
 	struct msm_gpio_set_tbl *cam_gpio_set_tbl;
 	uint8_t cam_gpio_set_tbl_size;
+	uint32_t gpio_no_mux;
+	uint32_t *camera_off_table;
+	uint8_t camera_off_table_size;
+	uint32_t *camera_on_table;
+	uint8_t camera_on_table_size;
 };
 
 enum msm_camera_i2c_mux_mode {
diff --git a/drivers/media/video/msm/Makefile b/drivers/media/video/msm/Makefile
index 8703669..67cd62e 100644
--- a/drivers/media/video/msm/Makefile
+++ b/drivers/media/video/msm/Makefile
@@ -44,7 +44,6 @@
 obj-$(CONFIG_QS_S5K4E1) += qs_s5k4e1.o qs_s5k4e1_reg.o
 obj-$(CONFIG_VB6801) += vb6801.o
 obj-$(CONFIG_IMX072) += imx072.o imx072_reg.o
-obj-$(CONFIG_WEBCAM_OV9726) += ov9726.o ov9726_reg.o
 obj-$(CONFIG_OV5647) += ov5647.o ov5647_reg.o
 obj-$(CONFIG_WEBCAM_OV7692) += ov7692.o
 obj-$(CONFIG_WEBCAM_OV7692_QRD) += ov7692_qrd.o
diff --git a/drivers/media/video/msm/actuators/dw9712_act.c b/drivers/media/video/msm/actuators/dw9712_act.c
index 562290f..546cffa 100644
--- a/drivers/media/video/msm/actuators/dw9712_act.c
+++ b/drivers/media/video/msm/actuators/dw9712_act.c
@@ -101,9 +101,9 @@
 
 	/* Determine sign direction */
 	if (dir == MOVE_NEAR)
-		sign_dir = 1;
+		sign_dir = 16;
 	else if (dir == MOVE_FAR)
-		sign_dir = -1;
+		sign_dir = -16;
 	else {
 		pr_err("Illegal focus direction\n");
 		rc = -EINVAL;
diff --git a/drivers/media/video/msm/io/msm_io_util.c b/drivers/media/video/msm/io/msm_io_util.c
index 207f8be..a04d6fd 100644
--- a/drivers/media/video/msm/io/msm_io_util.c
+++ b/drivers/media/video/msm/io/msm_io_util.c
@@ -95,32 +95,33 @@
 				curr_vreg->reg_name);
 			if (IS_ERR(reg_ptr[i])) {
 				pr_err("%s: %s get failed\n",
-				 __func__,
-				 curr_vreg->reg_name);
+					 __func__,
+					 curr_vreg->reg_name);
 				reg_ptr[i] = NULL;
 				goto vreg_get_fail;
 			}
 			if (curr_vreg->type == REG_LDO) {
 				rc = regulator_set_voltage(
-				reg_ptr[i],
-				curr_vreg->min_voltage,
-				curr_vreg->max_voltage);
+					reg_ptr[i],
+					curr_vreg->min_voltage,
+					curr_vreg->max_voltage);
 				if (rc < 0) {
-					pr_err(
-					"%s: %s set voltage failed\n",
-					__func__,
-					curr_vreg->reg_name);
+					pr_err("%s: %s set voltage failed\n",
+						__func__,
+						curr_vreg->reg_name);
 					goto vreg_set_voltage_fail;
 				}
-				rc = regulator_set_optimum_mode(
-					reg_ptr[i],
-					curr_vreg->op_mode);
-				if (rc < 0) {
-					pr_err(
-					"%s: %s set optimum mode failed\n",
-					__func__,
-					curr_vreg->reg_name);
-					goto vreg_set_opt_mode_fail;
+				if (curr_vreg->op_mode) {
+					rc = regulator_set_optimum_mode(
+						reg_ptr[i],
+						curr_vreg->op_mode);
+					if (rc < 0) {
+						pr_err("%s: %s set optimum"
+							"mode failed\n",
+							__func__,
+							curr_vreg->reg_name);
+						goto vreg_set_opt_mode_fail;
+					}
 				}
 			}
 		}
@@ -129,11 +130,12 @@
 			curr_vreg = &cam_vreg[i];
 			if (reg_ptr[i]) {
 				if (curr_vreg->type == REG_LDO) {
-					regulator_set_optimum_mode(
-						reg_ptr[i], 0);
+					if (curr_vreg->op_mode)
+						regulator_set_optimum_mode(
+							reg_ptr[i], 0);
 					regulator_set_voltage(
-						reg_ptr[i],
-						0, curr_vreg->max_voltage);
+						reg_ptr[i], 0, curr_vreg->
+						max_voltage);
 				}
 				regulator_put(reg_ptr[i]);
 				reg_ptr[i] = NULL;
@@ -171,13 +173,13 @@
 		for (i = 0; i < num_vreg; i++) {
 			if (IS_ERR(reg_ptr[i])) {
 				pr_err("%s: %s null regulator\n",
-				__func__, cam_vreg[i].reg_name);
+					__func__, cam_vreg[i].reg_name);
 				goto disable_vreg;
 			}
 			rc = regulator_enable(reg_ptr[i]);
 			if (rc < 0) {
 				pr_err("%s: %s enable failed\n",
-				__func__, cam_vreg[i].reg_name);
+					__func__, cam_vreg[i].reg_name);
 				goto disable_vreg;
 			}
 		}
@@ -194,6 +196,30 @@
 	return rc;
 }
 
+static int config_gpio_table(struct msm_camera_gpio_conf *gpio)
+{
+	int rc = 0, i = 0;
+	uint32_t *table_on;
+	uint32_t *table_off;
+	uint32_t len;
+
+	table_on = gpio->camera_on_table;
+	table_off = gpio->camera_off_table;
+	len = gpio->camera_on_table_size;
+
+	for (i = 0; i < len; i++) {
+		rc = gpio_tlmm_config(table_on[i], GPIO_CFG_ENABLE);
+		if (rc) {
+			pr_err("%s not able to get gpio\n", __func__);
+			for (i--; i >= 0; i--)
+				gpio_tlmm_config(table_off[i],
+					GPIO_CFG_ENABLE);
+			break;
+		}
+	}
+	return rc;
+}
+
 int msm_camera_request_gpio_table(struct msm_camera_sensor_info *sinfo,
 	int gpio_en)
 {
@@ -201,38 +227,49 @@
 	struct msm_camera_gpio_conf *gpio_conf =
 		sinfo->sensor_platform_info->gpio_conf;
 
-	if (gpio_conf->cam_gpio_req_tbl == NULL ||
-		gpio_conf->cam_gpio_common_tbl == NULL) {
-		pr_err("%s: NULL camera gpio table\n", __func__);
-		return -EFAULT;
+	if (!gpio_conf->gpio_no_mux) {
+		if (gpio_conf->cam_gpio_req_tbl == NULL ||
+			gpio_conf->cam_gpio_common_tbl == NULL) {
+			pr_err("%s: NULL camera gpio table\n", __func__);
+			return -EFAULT;
+		}
 	}
+	if (gpio_conf->gpio_no_mux)
+		config_gpio_table(gpio_conf);
 
 	if (gpio_en) {
-		if (gpio_conf->cam_gpiomux_conf_tbl != NULL) {
-			msm_gpiomux_install(
-				(struct msm_gpiomux_config *)gpio_conf->
-				cam_gpiomux_conf_tbl,
-				gpio_conf->cam_gpiomux_conf_tbl_size);
-		}
-		rc = gpio_request_array(gpio_conf->cam_gpio_common_tbl,
+		if (!gpio_conf->gpio_no_mux) {
+			if (gpio_conf->cam_gpiomux_conf_tbl != NULL) {
+				msm_gpiomux_install(
+					(struct msm_gpiomux_config *)
+					gpio_conf->cam_gpiomux_conf_tbl,
+					gpio_conf->cam_gpiomux_conf_tbl_size);
+			}
+			rc = gpio_request_array(gpio_conf->cam_gpio_common_tbl,
 				gpio_conf->cam_gpio_common_tbl_size);
-		if (rc < 0) {
-			pr_err("%s common gpio request failed\n", __func__);
-			return rc;
+			if (rc < 0) {
+				pr_err("%s common gpio request failed\n"
+						, __func__);
+				return rc;
+			}
 		}
-		rc = gpio_request_array(gpio_conf->cam_gpio_req_tbl,
+		if (gpio_conf->cam_gpio_req_tbl_size) {
+			rc = gpio_request_array(gpio_conf->cam_gpio_req_tbl,
 				gpio_conf->cam_gpio_req_tbl_size);
-		if (rc < 0) {
-			pr_err("%s camera gpio request failed\n", __func__);
-			gpio_free_array(gpio_conf->cam_gpio_common_tbl,
-				gpio_conf->cam_gpio_common_tbl_size);
-			return rc;
+			if (rc < 0) {
+				pr_err("%s camera gpio"
+					"request failed\n", __func__);
+				gpio_free_array(gpio_conf->cam_gpio_common_tbl,
+					gpio_conf->cam_gpio_common_tbl_size);
+				return rc;
+			}
 		}
 	} else {
 		gpio_free_array(gpio_conf->cam_gpio_req_tbl,
 				gpio_conf->cam_gpio_req_tbl_size);
-		gpio_free_array(gpio_conf->cam_gpio_common_tbl,
-			gpio_conf->cam_gpio_common_tbl_size);
+		if (!gpio_conf->gpio_no_mux)
+			gpio_free_array(gpio_conf->cam_gpio_common_tbl,
+				gpio_conf->cam_gpio_common_tbl_size);
 	}
 	return rc;
 }
@@ -252,7 +289,7 @@
 			usleep_range(gpio_conf->cam_gpio_set_tbl[i].delay,
 				gpio_conf->cam_gpio_set_tbl[i].delay + 1000);
 		}
-	} else {
+	} else if (!gpio_conf->gpio_no_mux) {
 		for (i = gpio_conf->cam_gpio_set_tbl_size - 1; i >= 0; i--) {
 			if (gpio_conf->cam_gpio_set_tbl[i].flags)
 				gpio_set_value_cansleep(
diff --git a/drivers/media/video/msm/msm_io_7x27a_v4l2.c b/drivers/media/video/msm/msm_io_7x27a_v4l2.c
index bee9f49..63547c8 100644
--- a/drivers/media/video/msm/msm_io_7x27a_v4l2.c
+++ b/drivers/media/video/msm/msm_io_7x27a_v4l2.c
@@ -97,33 +97,6 @@
 	clk_set_rate(clk, rate);
 }
 
-int msm_sensor_probe_on(struct device *dev)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = dev->platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camio_clk = camdev->ioclk;
-
-	rc = camdev->camera_gpio_on();
-	if (rc < 0)
-		return rc;
-
-	rc = msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
-	if (rc < 0)
-		camdev->camera_gpio_off();
-
-	return rc;
-}
-
-int msm_sensor_probe_off(struct device *dev)
-{
-	struct msm_camera_sensor_info *sinfo = dev->platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
-	camdev->camera_gpio_off();
-	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-}
-
 void msm_camio_vfe_blk_reset(void)
 {
 	uint32_t val;
@@ -152,28 +125,6 @@
 	usleep_range(10000, 11000);
 }
 
-int msm_camio_probe_on(struct platform_device *pdev)
-{
-	int rc = 0;
-	const struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camio_clk = camdev->ioclk;
-
-	rc = camdev->camera_gpio_on();
-	if (rc < 0)
-		return rc;
-	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
-}
-
-int msm_camio_probe_off(struct platform_device *pdev)
-{
-	const struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
-	camdev->camera_gpio_off();
-	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-}
-
 void msm_camio_set_perf_lvl(enum msm_bus_perf_setting perf_setting)
 {
 	switch (perf_setting) {
diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c
index a0ac70d..3e2ddee 100644
--- a/drivers/media/video/msm/msm_isp.c
+++ b/drivers/media/video/msm/msm_isp.c
@@ -127,6 +127,10 @@
 		case VFE_OUTPUTS_JPEG_AND_THUMB:
 			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_THUMBNAIL;
 			break;
+		case VFE_OUTPUTS_PREVIEW:
+		case VFE_OUTPUTS_VIDEO:
+			image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
+			break;
 		default:
 			image_mode = -1;
 			break;
@@ -402,6 +406,8 @@
 			stats.cs.buff = stats.buffer;
 			stats.cs.fd = stats.fd;
 			break;
+		case MSG_ID_STATS_AWB_AEC:
+			break;
 		default:
 			pr_err("%s: Invalid msg type", __func__);
 			break;
@@ -722,6 +728,7 @@
 	case CMD_AXI_CFG_ZSL_ALL_CHNLS:
 	case CMD_RAW_PICT_AXI_CFG:
 	case CMD_AXI_CFG_PRIM:
+	case CMD_AXI_CFG_SEC:
 	case CMD_AXI_CFG_PRIM_ALL_CHNLS:
 	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC:
 	case CMD_AXI_CFG_PRIM|CMD_AXI_CFG_SEC_ALL_CHNLS:
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
index 638c51d..07a4c89 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
@@ -327,6 +327,9 @@
 	{VFE_CMD_SCALE_OUTPUT2_CONFIG, VFE_SCALE_OUTPUT2_CONFIG,
 		QDSP_SCALEQUEUE, "VFE_CMD_SCALE_OUTPUT2_CONFIG",
 		"VFE_SCALE_OUTPUT2_CONFIG"},
+	{VFE_CMD_CAPTURE_RAW, VFE_START, QDSP_CMDQUEUE,
+			"VFE_CMD_CAPTURE_RAW", "VFE_START"},
+	{VFE_CMD_RECONFIG_VFE, VFE_MAX, VFE_MAX},
 };
 
 
@@ -400,9 +403,9 @@
 	unsigned char buf[256];
 	struct msm_free_buf *free_buf = NULL;
 	struct vfe_outputack fack;
+	int i;
 
 	CDBG("%s:id=%d\n", __func__, id);
-
 	if (id != VFE_ADSP_EVENT) {
 		data = kzalloc(len, GFP_KERNEL);
 		if (!data) {
@@ -434,8 +437,9 @@
 			cbcr_phy = outch->ping.ch_paddr[1];
 			CDBG("MSG_OUTPUT_S: %x %x\n",
 				(unsigned int)y_phy, (unsigned int)cbcr_phy);
-			vfe_send_outmsg(&vfe2x_ctrl->subdev, MSG_ID_OUTPUT_S,
-							y_phy, cbcr_phy);
+			vfe_send_outmsg(&vfe2x_ctrl->subdev,
+					MSG_ID_OUTPUT_PRIMARY,
+						y_phy, cbcr_phy);
 			break;
 		case MSG_OUTPUT_T:
 			outch = &vfe2x_ctrl->thumb;
@@ -443,7 +447,8 @@
 			cbcr_phy = outch->ping.ch_paddr[1];
 			CDBG("MSG_OUTPUT_T: %x %x\n",
 				(unsigned int)y_phy, (unsigned int)cbcr_phy);
-			vfe_send_outmsg(&vfe2x_ctrl->subdev, MSG_ID_OUTPUT_T,
+			vfe_send_outmsg(&vfe2x_ctrl->subdev,
+						MSG_ID_OUTPUT_SECONDARY,
 							y_phy, cbcr_phy);
 			break;
 		case MSG_OUTPUT1:
@@ -454,7 +459,7 @@
 			} else {
 				free_buf = vfe2x_check_free_buffer(
 					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_P);
+					VFE_MSG_OUTPUT_PRIMARY);
 			      CDBG("free_buf = %x\n", (unsigned int) free_buf);
 			      if (free_buf) {
 					fack.header = VFE_OUTPUT2_ACK;
@@ -489,7 +494,22 @@
 
 			CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
 				 y_phy, cbcr_phy);
-
+			if (free_buf) {
+				for (i = 0; i < 3; i++) {
+					if (vfe2x_ctrl->free_buf.buf[i].
+							ch_paddr[0] == y_phy) {
+						vfe2x_ctrl->free_buf.
+							buf[i].ch_paddr[0] =
+							free_buf->ch_paddr[0];
+						vfe2x_ctrl->free_buf.
+							buf[i].ch_paddr[1] =
+							free_buf->ch_paddr[1];
+						break;
+					}
+				}
+				if (i == 3)
+					CDBG("Address doesnt match\n");
+			}
 			memcpy(((struct vfe_frame_extra *)extdata),
 				&((struct vfe_endframe *)data)->extra,
 				sizeof(struct vfe_frame_extra));
@@ -497,8 +517,8 @@
 			vfe2x_ctrl->vfeFrameId =
 				((struct vfe_frame_extra *)extdata)->frame_id;
 			vfe_send_outmsg(&vfe2x_ctrl->subdev,
-							MSG_ID_OUTPUT_P,
-							y_phy, cbcr_phy);
+						MSG_ID_OUTPUT_PRIMARY,
+						y_phy, cbcr_phy);
 			break;
 		case MSG_RESET_ACK:
 		case MSG_START_ACK:
@@ -509,11 +529,55 @@
 			vfe2x_send_isp_msg(vfe2x_ctrl, msgs_map[id].isp_id);
 			if (id == MSG_START_ACK)
 				vfe2x_ctrl->vfe_started = 1;
+			if (id == MSG_VFE_ERROR) {
+				uint16_t *ptr;
+				struct vfe_error_msg *VFE_ErrorMessageBuffer
+					= data;
+				ptr = data;
+				CDBG("Error: %x %x\n", ptr[0], ptr[1]);
+				CDBG("CAMIF_Error              = %d\n",
+					VFE_ErrorMessageBuffer->camif_error);
+				CDBG("output1YBusOverflow      = %d\n",
+					VFE_ErrorMessageBuffer->
+					output1ybusoverflow);
+				CDBG("output1CbCrBusOverflow   = %d\n",
+					VFE_ErrorMessageBuffer->
+					output1cbcrbusoverflow);
+				CDBG("output2YBusOverflow      = %d\n",
+					VFE_ErrorMessageBuffer->
+					output2ybusoverflow);
+				CDBG("output2CbCrBusOverflow   = %d\n",
+						VFE_ErrorMessageBuffer->
+						output2cbcrbusoverflow);
+				CDBG("autofocusStatBusOverflow = %d\n",
+						VFE_ErrorMessageBuffer->
+						autofocusstatbusoverflow);
+				CDBG("WB_EXPStatBusOverflow    = %d\n",
+						VFE_ErrorMessageBuffer->
+						wb_expstatbusoverflow);
+				CDBG("AXIError                 = %d\n",
+						VFE_ErrorMessageBuffer->
+						axierror);
+				CDBG("CAMIF_Staus              = %d\n",
+						VFE_ErrorMessageBuffer->
+						camif_staus);
+				CDBG("pixel_count              = %d\n",
+						VFE_ErrorMessageBuffer->
+						pixel_count);
+				CDBG("line_count               = %d\n",
+						VFE_ErrorMessageBuffer->
+						line_count);
+			}
 			break;
 		case MSG_SOF:
 			vfe2x_ctrl->vfeFrameId++;
 			if (vfe2x_ctrl->vfeFrameId == 0)
 				vfe2x_ctrl->vfeFrameId = 1; /* wrapped back */
+			if ((op_mode & SNAPSHOT_MASK_MODE) && !raw_mode) {
+				pr_err("Ignore SOF for snapshot\n");
+				kfree(data);
+				return;
+			}
 			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_SOF_ACK);
 			if (raw_mode)
 				vfe2x_send_isp_msg(vfe2x_ctrl,
@@ -584,9 +648,13 @@
 	unsigned long *bptr;
 	int    cnt;
 	int rc = 0;
+	int o_mode = 0;
 
+	if (op_mode & SNAPSHOT_MASK_MODE)
+		o_mode = SNAPSHOT_MASK_MODE;
 
-	if (mode == OUTPUT_1) {
+	if (mode == OUTPUT_SEC) {
+		/* Thumbnail */
 		ao->output1buffer1_y_phy = ad->ping.ch_paddr[0];
 		ao->output1buffer1_cbcr_phy = ad->ping.ch_paddr[1];
 		ao->output1buffer2_y_phy = ad->pong.ch_paddr[0];
@@ -598,9 +666,8 @@
 			*bptr = ad->pong.ch_paddr[1];
 			bptr++;
 		}
-	}
-
-	if (mode == OUTPUT_2) {
+	} else if (mode == OUTPUT_PRIM && o_mode != SNAPSHOT_MASK_MODE) {
+		/* Preview */
 		ao->output2buffer1_y_phy = ad->ping.ch_paddr[0];
 		ao->output2buffer1_cbcr_phy = ad->ping.ch_paddr[1];
 		ao->output2buffer2_y_phy = ad->pong.ch_paddr[0];
@@ -614,9 +681,30 @@
 			*bptr = ad->pong.ch_paddr[1];
 			bptr++;
 		}
-	}
-
-	if (mode == OUTPUT_1_AND_2) {
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer1_y_phy,
+			(unsigned int)ao->output2buffer1_cbcr_phy);
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer2_y_phy,
+			(unsigned int)ao->output2buffer2_cbcr_phy);
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer3_y_phy,
+			(unsigned int)ao->output2buffer3_cbcr_phy);
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer4_y_phy,
+			(unsigned int)ao->output2buffer4_cbcr_phy);
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer5_y_phy,
+			(unsigned int)ao->output2buffer5_cbcr_phy);
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer6_y_phy,
+			(unsigned int)ao->output2buffer6_cbcr_phy);
+		CDBG("%x %x\n", (unsigned int)ao->output2buffer7_y_phy,
+			(unsigned int)ao->output2buffer7_cbcr_phy);
+		vfe2x_ctrl->free_buf.buf[0].ch_paddr[0] = ad->ping.ch_paddr[0];
+		vfe2x_ctrl->free_buf.buf[0].ch_paddr[1] = ad->ping.ch_paddr[1];
+		vfe2x_ctrl->free_buf.buf[1].ch_paddr[0] = ad->pong.ch_paddr[0];
+		vfe2x_ctrl->free_buf.buf[1].ch_paddr[1] = ad->pong.ch_paddr[1];
+		vfe2x_ctrl->free_buf.buf[2].ch_paddr[0] =
+			ad->free_buf.ch_paddr[0];
+		vfe2x_ctrl->free_buf.buf[2].ch_paddr[1] =
+			ad->free_buf.ch_paddr[1];
+	} else if (mode == OUTPUT_PRIM && o_mode == SNAPSHOT_MASK_MODE) {
+		vfe2x_ctrl->reconfig_vfe = 0;
 		if (raw_mode) {
 			ao->output2buffer1_y_phy = ad->ping.ch_paddr[0];
 			ao->output2buffer1_cbcr_phy = ad->ping.ch_paddr[0];
@@ -632,7 +720,7 @@
 		for (cnt = 0; cnt < 6; cnt++) {
 			*bptr = ad->pong.ch_paddr[0];
 			bptr++;
-			*bptr = ad->pong.ch_paddr[0];
+			*bptr = ad->pong.ch_paddr[1];
 			bptr++;
 		}
 	}
@@ -664,12 +752,12 @@
 
 	vfe2x_subdev_notify(id, path);
 	if (op_mode & SNAPSHOT_MASK_MODE) {
-		if (path == VFE_MSG_OUTPUT_S)
+		if (path == VFE_MSG_OUTPUT_PRIMARY)
 			outch = &vfe2x_ctrl->snap;
-		else if (path == VFE_MSG_OUTPUT_T)
+		else if (path == VFE_MSG_OUTPUT_SECONDARY)
 			outch = &vfe2x_ctrl->thumb;
 	} else {
-		if (path == VFE_MSG_OUTPUT_P)
+		if (path == VFE_MSG_OUTPUT_PRIMARY)
 			outch = &vfe2x_ctrl->prev;
 	}
 	if (outch->free_buf.ch_paddr[0])
@@ -684,15 +772,14 @@
 	int rc = 0;
 
 	vfe2x_subdev_notify(id, path);
-
 	CDBG("Opmode = %d\n", op_mode);
 	if (op_mode & SNAPSHOT_MASK_MODE) {
-		if (path == VFE_MSG_OUTPUT_S)
+		if (path == VFE_MSG_OUTPUT_PRIMARY)
 			outch = &vfe2x_ctrl->snap;
-		else if (path == VFE_MSG_OUTPUT_T)
+		else if (path == VFE_MSG_OUTPUT_SECONDARY)
 			outch = &vfe2x_ctrl->thumb;
 	} else {
-		if (path == VFE_MSG_OUTPUT_P)
+		if (path == VFE_MSG_OUTPUT_PRIMARY)
 			outch = &vfe2x_ctrl->prev;
 	}
 	if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
@@ -711,13 +798,14 @@
 	struct buf_info *ch = NULL;
 
 	CDBG("path = %d op_mode = %d\n", path, op_mode);
+	/* TODO: Remove Mode specific stuff */
 	if (op_mode & SNAPSHOT_MASK_MODE) {
-		if (path == VFE_MSG_OUTPUT_T)
+		if (path == VFE_MSG_OUTPUT_SECONDARY)
 			ch = &vfe2x_ctrl->thumb;
-		else if (path == VFE_MSG_OUTPUT_S)
+		else if (path == VFE_MSG_OUTPUT_PRIMARY)
 			ch = &vfe2x_ctrl->snap;
 	} else {
-		if (path == VFE_MSG_OUTPUT_P)
+		if (path == VFE_MSG_OUTPUT_PRIMARY)
 			ch = &vfe2x_ctrl->prev;
 	}
 
@@ -777,11 +865,11 @@
 		if (op_mode & SNAPSHOT_MASK_MODE) {
 			free_buf = vfe2x_check_free_buffer(
 					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_T);
+					VFE_MSG_OUTPUT_SECONDARY);
 		} else {
 			free_buf = vfe2x_check_free_buffer(
 					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_P);
+					VFE_MSG_OUTPUT_PRIMARY);
 			if (free_buf) {
 				fack.header = VFE_OUTPUT2_ACK;
 
@@ -875,6 +963,7 @@
 		break;
 	case CMD_STATS_AF_ENABLE:
 	case CMD_STATS_AF_AXI_CFG: {
+		CDBG("CMD_STATS_AF_ENABLE CMD_STATS_AF_AXI_CFG\n");
 		axid = data;
 		if (!axid) {
 			rc = -EFAULT;
@@ -908,6 +997,7 @@
 			goto config_failure;
 		}
 		*(uint32_t *)sfcfg = header;
+		CDBG("Number of buffers = %d\n", axid->bufnum1);
 		if (axid->bufnum1 > 0) {
 			regptr = &axid->region[0];
 
@@ -973,6 +1063,11 @@
 			op_mode = vfe2x_ctrl->start_cmd.mode_of_operation;
 			return rc;
 		}
+		if (vfecmd.id == VFE_CMD_RECONFIG_VFE) {
+			CDBG("VFE is RECONFIGURED\n");
+			vfe2x_ctrl->reconfig_vfe = 1;
+			return 0;
+		}
 		if (vfecmd.length > 256 - 4) {
 			cmd_data_alloc =
 			cmd_data = kmalloc(vfecmd.length + 4, GFP_ATOMIC);
@@ -1002,13 +1097,12 @@
 		if (queue == QDSP_CMDQUEUE) {
 			switch (vfecmd.id) {
 			case VFE_CMD_RESET:
-				msm_adsp_enable(qcam_mod);
-				msm_adsp_enable(vfe_mod);
 				msm_camio_vfe_blk_reset();
 				vfestopped = 0;
 				break;
 			case VFE_CMD_START:
 			case VFE_CMD_CAPTURE:
+			case VFE_CMD_CAPTURE_RAW:
 				spin_lock_irqsave(&vfe2x_ctrl->table_lock,
 									flags);
 				if (!list_empty(&vfe2x_ctrl->table_q)) {
@@ -1041,9 +1135,63 @@
 		} /* QDSP_CMDQUEUE */
 	}
 		break;
-	case CMD_AXI_CFG_PREVIEW: {
-		CDBG("CMD_AXI_CFG_PREVIEW\n");
+	case CMD_AXI_CFG_SEC: {
+		CDBG("CMD_AXI_CFG_SEC\n");
 		raw_mode = 0;
+		vfe2x_ctrl->output_mode =  OUTPUT_SEC;
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			pr_err("NULL axio\n");
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user((char *)axio + 4,
+					(void __user *)(vfecmd.value),
+					sizeof(struct axiout))) {
+			CDBG("copy_from_user failed\n");
+			rc = -EFAULT;
+			goto config_done;
+		}
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_V2X_CAPTURE,
+						VFE_MSG_OUTPUT_SECONDARY);
+		else
+			rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_V2X_PREVIEW,
+						VFE_MSG_OUTPUT_SECONDARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for preview", __func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+
+		if (!(op_mode & SNAPSHOT_MASK_MODE))
+			free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_SECONDARY);
+		header = cmds_map[vfecmd.id].vfe_id;
+		queue = cmds_map[vfecmd.id].queue;
+		if (header == -1 && queue == -1) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+		*(uint32_t *)axio = header;
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			vfe_7x_config_axi(OUTPUT_SEC,
+					&vfe2x_ctrl->thumb, axio);
+		else
+			vfe_7x_config_axi(OUTPUT_SEC,
+					&vfe2x_ctrl->video, axio);
+		cmd_data = axio;
+	}
+		break;
+	case CMD_AXI_CFG_PRIM: {
+		CDBG("CMD_AXI_CFG_PRIM : %d\n", op_mode);
+		raw_mode = 0;
+		vfe2x_ctrl->output_mode =  OUTPUT_PRIM;
 		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
 		if (!axio) {
 			pr_err("NULL axio\n");
@@ -1058,18 +1206,40 @@
 			rc = -EFAULT;
 			goto config_done;
 		}
-		rc = vfe2x_configure_pingpong_buffers(VFE_MSG_V2X_PREVIEW,
-							VFE_MSG_OUTPUT_P);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for preview", __func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-
-		free_buf = vfe2x_check_free_buffer(
+		if (!vfe2x_ctrl->reconfig_vfe) {
+			if (op_mode & SNAPSHOT_MASK_MODE)
+				rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_V2X_CAPTURE,
+						VFE_MSG_OUTPUT_PRIMARY);
+			else
+				rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_V2X_PREVIEW,
+						VFE_MSG_OUTPUT_PRIMARY);
+			if (rc < 0) {
+				pr_err("%s error configuring pingpong buffers"
+					" for preview", __func__);
+				rc = -EINVAL;
+				goto config_done;
+			}
+			if (!(op_mode & SNAPSHOT_MASK_MODE))
+				free_buf = vfe2x_check_free_buffer(
 					VFE_MSG_OUTPUT_IRQ,
-					VFE_MSG_OUTPUT_P);
+					VFE_MSG_OUTPUT_PRIMARY);
+		} else {
+			vfe2x_ctrl->prev.ping.ch_paddr[0] =
+				vfe2x_ctrl->free_buf.buf[0].ch_paddr[0];
+			vfe2x_ctrl->prev.ping.ch_paddr[1] =
+				vfe2x_ctrl->free_buf.buf[0].ch_paddr[1];
+			vfe2x_ctrl->prev.pong.ch_paddr[0] =
+				vfe2x_ctrl->free_buf.buf[1].ch_paddr[0];
+			vfe2x_ctrl->prev.pong.ch_paddr[1] =
+				vfe2x_ctrl->free_buf.buf[1].ch_paddr[1];
+			vfe2x_ctrl->prev.free_buf.ch_paddr[0] =
+				vfe2x_ctrl->free_buf.buf[2].ch_paddr[0];
+			vfe2x_ctrl->prev.free_buf.ch_paddr[1] =
+				vfe2x_ctrl->free_buf.buf[2].ch_paddr[1];
+			vfe2x_ctrl->reconfig_vfe = 0;
+		}
 		header = cmds_map[vfecmd.id].vfe_id;
 		queue = cmds_map[vfecmd.id].queue;
 		if (header == -1 && queue == -1) {
@@ -1077,12 +1247,93 @@
 			goto config_done;
 		}
 		*(uint32_t *)axio = header;
-		vfe_7x_config_axi(OUTPUT_2, &vfe2x_ctrl->prev, axio);
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->snap, axio);
+		else
+			vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->prev, axio);
+		cmd_data = axio;
+	}
+		break;
+	case CMD_AXI_CFG_SEC|CMD_AXI_CFG_PRIM: {
+		CDBG("CMD_AXI_CFG_SEC|PRIM\n");
+		raw_mode = 0;
+		vfe2x_ctrl->output_mode =  OUTPUT_SEC|OUTPUT_PRIM;
+		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+		if (!axio) {
+			pr_err("NULL axio\n");
+			rc = -ENOMEM;
+			goto config_failure;
+		}
+
+		if (copy_from_user((char *)axio + 4,
+					(void __user *)(vfecmd.value),
+					sizeof(struct axiout))) {
+			pr_err("copy_from_user failed\n");
+			rc = -EFAULT;
+			goto config_done;
+		}
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_V2X_CAPTURE,
+						VFE_MSG_OUTPUT_SECONDARY);
+		else
+			rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_V2X_PREVIEW,
+						VFE_MSG_OUTPUT_SECONDARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for preview", __func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+
+		if (!(op_mode & SNAPSHOT_MASK_MODE))
+			free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_SECONDARY);
+		header = cmds_map[vfecmd.id].vfe_id;
+		queue = cmds_map[vfecmd.id].queue;
+		if (header == -1 && queue == -1) {
+			rc = -EFAULT;
+			goto config_done;
+		}
+		*(uint32_t *)axio = header;
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			vfe_7x_config_axi(OUTPUT_SEC, &vfe2x_ctrl->thumb, axio);
+		else
+			vfe_7x_config_axi(OUTPUT_SEC, &vfe2x_ctrl->prev, axio);
+
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_V2X_CAPTURE,
+						VFE_MSG_OUTPUT_PRIMARY);
+		else
+			rc = vfe2x_configure_pingpong_buffers(
+						VFE_MSG_V2X_PREVIEW,
+						VFE_MSG_OUTPUT_PRIMARY);
+		if (rc < 0) {
+			pr_err("%s error configuring pingpong buffers"
+				" for preview", __func__);
+			rc = -EINVAL;
+			goto config_done;
+		}
+
+		if (!(op_mode & SNAPSHOT_MASK_MODE))
+			free_buf = vfe2x_check_free_buffer(
+					VFE_MSG_OUTPUT_IRQ,
+					VFE_MSG_OUTPUT_PRIMARY);
+		if (op_mode & SNAPSHOT_MASK_MODE)
+			vfe_7x_config_axi(OUTPUT_PRIM,
+					&vfe2x_ctrl->snap, axio);
+		else
+			vfe_7x_config_axi(OUTPUT_PRIM,
+					&vfe2x_ctrl->prev, axio);
 		cmd_data = axio;
 	}
 		break;
 	case CMD_RAW_PICT_AXI_CFG: {
 		CDBG("CMD_RAW_PICT_AXI_CFG:%d\n", op_mode);
+		vfe2x_ctrl->output_mode =  OUTPUT_PRIM;
 		raw_mode = 1;
 		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
 		if (!axio) {
@@ -1099,7 +1350,7 @@
 		header = cmds_map[vfecmd.id].vfe_id;
 		queue = cmds_map[vfecmd.id].queue;
 		rc = vfe2x_configure_pingpong_buffers(VFE_MSG_V2X_CAPTURE,
-							VFE_MSG_OUTPUT_S);
+						VFE_MSG_OUTPUT_PRIMARY);
 		if (rc < 0) {
 			pr_err("%s error configuring pingpong buffers"
 				" for preview", __func__);
@@ -1111,50 +1362,7 @@
 			goto config_done;
 		}
 		*(uint32_t *)axio = header;
-		vfe_7x_config_axi(OUTPUT_1_AND_2, &vfe2x_ctrl->snap, axio);
-		cmd_data = axio;
-	}
-		break;
-	case CMD_AXI_CFG_SNAP: {
-		raw_mode = 0;
-		CDBG("CMD_AXI_CFG_SNAP :%d\n", op_mode);
-		axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
-		if (!axio) {
-			rc = -ENOMEM;
-			goto config_failure;
-		}
-
-		if (copy_from_user((char *)axio + 4,
-					(void __user *)(vfecmd.value),
-					sizeof(struct axiout))) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-		header = cmds_map[vfecmd.id].vfe_id;
-		queue = cmds_map[vfecmd.id].queue;
-		rc = vfe2x_configure_pingpong_buffers(VFE_MSG_V2X_CAPTURE,
-							VFE_MSG_OUTPUT_S);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for preview", __func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		if (header == -1 && queue == -1) {
-			rc = -EFAULT;
-			goto config_done;
-		}
-		*(uint32_t *)axio = header;
-		vfe_7x_config_axi(OUTPUT_1_AND_2, &vfe2x_ctrl->snap, axio);
-		rc = vfe2x_configure_pingpong_buffers(VFE_MSG_V2X_CAPTURE,
-							VFE_MSG_OUTPUT_T);
-		if (rc < 0) {
-			pr_err("%s error configuring pingpong buffers"
-				" for preview", __func__);
-			rc = -EINVAL;
-			goto config_done;
-		}
-		vfe_7x_config_axi(OUTPUT_1, &vfe2x_ctrl->thumb, axio);
+		vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->snap, axio);
 		cmd_data = axio;
 	}
 		break;
@@ -1169,6 +1377,7 @@
 	CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
 	if (queue == QDSP_TABLEQUEUE &&
 			vfe2x_ctrl->tableack_pending) {
+		CDBG("store table cmd\n");
 		table_pending = kzalloc(sizeof(struct table_cmd), GFP_ATOMIC);
 		if (!table_pending) {
 			rc = -ENOMEM;
@@ -1188,12 +1397,14 @@
 		spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
 	} else {
 		if (queue == QDSP_TABLEQUEUE) {
+			CDBG("sending table cmd\n");
 			spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
 			rc = msm_adsp_write(vfe_mod, queue,
 				cmd_data, vfecmd.length + 4);
 			vfe2x_ctrl->tableack_pending = 1;
 			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
 		} else {
+			CDBG("send n-table cmd\n");
 			if (*(uint32_t *)cmd_data == VFE_OUTPUT2_ACK) {
 				uint32_t *ptr = cmd_data;
 				CDBG("%x %x %x\n", ptr[0], ptr[1], ptr[2]);
@@ -1263,6 +1474,8 @@
 		rc = -EBUSY;
 		goto get_vfe_fail;
 	}
+	msm_adsp_enable(qcam_mod);
+	msm_adsp_enable(vfe_mod);
 	return 0;
 
 get_vfe_fail:
@@ -1287,6 +1500,7 @@
 
 void msm_vfe_subdev_release(struct platform_device *pdev)
 {
+	CDBG("msm_cam_clk_enable: disable vfe_clk\n");
 	msm_cam_clk_enable(&vfe2x_ctrl->pdev->dev, vfe2x_clk_info,
 			vfe2x_ctrl->vfe_clk, ARRAY_SIZE(vfe2x_clk_info), 0);
 	vfe_syncdata = NULL;
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.h b/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
index 0f7fb60..33d6c17 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
@@ -51,6 +51,10 @@
 	struct msm_free_buf free_buf;
 } __packed;
 
+struct prev_free_buf_info {
+	struct msm_free_buf buf[3];
+};
+
 struct vfe_cmd_start {
 	uint32_t input_source:1;
 	uint32_t mode_of_operation:1;
@@ -75,10 +79,13 @@
 } __packed;
 
 struct vfe2x_ctrl_type {
+	uint16_t output_mode;
 	struct buf_info prev;
+	struct buf_info video;
 	struct buf_info snap;
 	struct buf_info raw;
 	struct buf_info thumb;
+	struct prev_free_buf_info free_buf;
 
 	spinlock_t  table_lock;
 	struct list_head table_q;
@@ -97,6 +104,7 @@
 	struct platform_device *pdev;
 	struct clk *vfe_clk[3];
 	spinlock_t  sd_notify_lock;
+	uint32_t    reconfig_vfe;
 } __packed;
 
 struct vfe_frame_extra {
@@ -379,6 +387,21 @@
 	int state;
 	int timeout;
 };
+struct vfe_error_msg {
+	unsigned int camif_error:1;
+	unsigned int output1ybusoverflow:1;
+	unsigned int output1cbcrbusoverflow:1;
+	unsigned int output2ybusoverflow:1;
+	unsigned int output2cbcrbusoverflow:1;
+	unsigned int autofocusstatbusoverflow:1;
+	unsigned int wb_expstatbusoverflow:1;
+	unsigned int axierror:1;
+	unsigned int /* reserved */ : 24;
+	unsigned int camif_staus:1;
+	unsigned int pixel_count:14;
+	unsigned int line_count:14;
+	unsigned int /*reserved */ : 3;
+} __packed;
 
 static struct msm_free_buf *vfe2x_check_free_buffer(int id, int path);
 
diff --git a/drivers/media/video/msm/sensors/mt9e013_v4l2.c b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
index 924cbc9..a6bc653 100644
--- a/drivers/media/video/msm/sensors/mt9e013_v4l2.c
+++ b/drivers/media/video/msm/sensors/mt9e013_v4l2.c
@@ -28,12 +28,6 @@
 };
 
 static struct msm_camera_i2c_reg_conf mt9e013_prev_settings[] = {
-	{0x0300, 0x0004},/*VT_PIX_CLK_DIV*/
-	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
-	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
-	{0x0306, 0x003A},/*PLL_MULTIPLIER*/
-	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
-	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
 	/*Output Size (1632x1224)*/
 	{0x0344, 0x0008},/*X_ADDR_START*/
 	{0x0348, 0x0CC9},/*X_ADDR_END*/
@@ -56,12 +50,6 @@
 };
 
 static struct msm_camera_i2c_reg_conf mt9e013_snap_settings[] = {
-	{0x0300, 0x0004},/*VT_PIX_CLK_DIV*/
-	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
-	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
-	{0x0306, 0x003A},/*PLL_MULTIPLIER*/
-	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
-	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
 	/*Output Size (3264x2448)*/
 	{0x0344, 0x0000},/*X_ADDR_START */
 	{0x0348, 0x0CCF},/*X_ADDR_END*/
@@ -172,14 +160,14 @@
 	{0x31B8, 0x0E3F},/*MIPI_TIMING_2*/
 	/*set data to RAW10 format*/
 	{0x0112, 0x0A0A},/*CCP_DATA_FORMAT*/
-	{0x30F0, 0x8000},/*VCM CONTROL*/
+	{0x30F0, 0x800D},/*VCM CONTROL*/
 
 	{0x3044, 0x0590},
 	{0x306E, 0xFC80},
 	{0x30B2, 0xC000},
 	{0x30D6, 0x0800},
 	{0x316C, 0xB42F},
-	{0x316E, 0x869C},
+	{0x316E, 0x869A},
 	{0x3170, 0x210E},
 	{0x317A, 0x010E},
 	{0x31E0, 0x1FB9},
@@ -188,17 +176,19 @@
 	{0x37C2, 0x0000},
 	{0x37C4, 0x0000},
 	{0x37C6, 0x0000},
+	{0x3E00, 0x0011},
 	{0x3E02, 0x8801},
-	{0x3E04, 0x2301},
+	{0x3E04, 0x2801},
 	{0x3E06, 0x8449},
 	{0x3E08, 0x6841},
 	{0x3E0A, 0x400C},
 	{0x3E0C, 0x1001},
-	{0x3E0E, 0x2103},
+	{0x3E0E, 0x2603},
 	{0x3E10, 0x4B41},
-	{0x3E12, 0x4B26},
+	{0x3E12, 0x4B24},
+	{0x3E14, 0xA3CF},
 	{0x3E16, 0x8802},
-	{0x3E18, 0x84FF},
+	{0x3E18, 0x8401},
 	{0x3E1A, 0x8601},
 	{0x3E1C, 0x8401},
 	{0x3E1E, 0x840A},
@@ -207,41 +197,56 @@
 	{0x3E24, 0x00FF},
 	{0x3E26, 0x0088},
 	{0x3E28, 0x2E8A},
+	{0x3E30, 0x0000},
 	{0x3E32, 0x8801},
-	{0x3E34, 0x4024},
+	{0x3E34, 0x4029},
+	{0x3E36, 0x00FF},
 	{0x3E38, 0x8469},
-	{0x3E3C, 0x2301},
-	{0x3E3E, 0x3E25},
+	{0x3E3A, 0x00FF},
+	{0x3E3C, 0x2801},
+	{0x3E3E, 0x3E2A},
 	{0x3E40, 0x1C01},
-	{0x3E42, 0x8486},
+	{0x3E42, 0xFF84},
 	{0x3E44, 0x8401},
-	{0x3E46, 0x00FF},
+	{0x3E46, 0x0C01},
 	{0x3E48, 0x8401},
-	{0x3E4A, 0x8601},
+	{0x3E4A, 0x00FF},
 	{0x3E4C, 0x8402},
-	{0x3E4E, 0x00FF},
-	{0x3E50, 0x6623},
+	{0x3E4E, 0x8984},
+	{0x3E50, 0x6628},
 	{0x3E52, 0x8340},
 	{0x3E54, 0x00FF},
 	{0x3E56, 0x4A42},
-	{0x3E58, 0x2203},
-	{0x3E5A, 0x674D},
-	{0x3E5C, 0x3F25},
+	{0x3E58, 0x2703},
+	{0x3E5A, 0x6752},
+	{0x3E5C, 0x3F2A},
 	{0x3E5E, 0x846A},
 	{0x3E60, 0x4C01},
 	{0x3E62, 0x8401},
 	{0x3E66, 0x3901},
+	{0x3E90, 0x2C01},
+	{0x3E98, 0x2B02},
+	{0x3E92, 0x2A04},
+	{0x3E94, 0x2509},
+	{0x3E96, 0x0000},
+	{0x3E9A, 0x2905},
+	{0x3E9C, 0x00FF},
 	{0x3ECC, 0x00EB},
 	{0x3ED0, 0x1E24},
 	{0x3ED4, 0xAFC4},
 	{0x3ED6, 0x909B},
-	{0x3ED8, 0x0006},
-	{0x3EDA, 0xCFC6},
-	{0x3EDC, 0x4FE4},
 	{0x3EE0, 0x2424},
 	{0x3EE2, 0x9797},
 	{0x3EE4, 0xC100},
-	{0x3EE6, 0x0540}
+	{0x3EE6, 0x0540},
+	{0x3174, 0x8000},
+	/* PLL settings */
+	{0x0300, 0x0004},/*VT_PIX_CLK_DIV*/
+	{0x0302, 0x0001},/*VT_SYS_CLK_DIV*/
+	{0x0304, 0x0002},/*PRE_PLL_CLK_DIV*/
+	{0x0306, 0x003A},/*PLL_MULTIPLIER*/
+	{0x0308, 0x000A},/*OP_PIX_CLK_DIV*/
+	{0x030A, 0x0001},/*OP_SYS_CLK_DIV*/
 };
 
 static struct v4l2_subdev_info mt9e013_subdev_info[] = {
@@ -498,6 +503,7 @@
 	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(mt9e013_subdev_info),
 	.sensor_v4l2_subdev_ops = &mt9e013_subdev_ops,
 	.func_tbl = &mt9e013_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
 };
 
 module_init(msm_sensor_init_module);
diff --git a/drivers/media/video/msm/sensors/ov9726_v4l2.c b/drivers/media/video/msm/sensors/ov9726_v4l2.c
index e345717..17291ff 100644
--- a/drivers/media/video/msm/sensors/ov9726_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov9726_v4l2.c
@@ -271,6 +271,7 @@
 	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov9726_subdev_info),
 	.sensor_v4l2_subdev_ops = &ov9726_subdev_ops,
 	.func_tbl = &ov9726_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
 };
 
 module_init(msm_sensor_init_module);
diff --git a/drivers/media/video/msm/sensors/s5k4e1_v4l2.c b/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
index 1f99119..699f0dd 100644
--- a/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
+++ b/drivers/media/video/msm/sensors/s5k4e1_v4l2.c
@@ -196,8 +196,8 @@
 		.y_output = 0x7A8,
 		.line_length_pclk = 0xAB2,
 		.frame_length_lines = 0x7B4,
-		.vt_pixel_clk = 816000000,
-		.op_pixel_clk = 816000000,
+		.vt_pixel_clk = 81600000,
+		.op_pixel_clk = 81600000,
 		.binning_factor = 0,
 	},
 	{
@@ -205,8 +205,8 @@
 		.y_output = 0x3D4,
 		.line_length_pclk = 0xAB2,
 		.frame_length_lines = 0x3E0,
-		.vt_pixel_clk = 816000000,
-		.op_pixel_clk = 816000000,
+		.vt_pixel_clk = 81600000,
+		.op_pixel_clk = 81600000,
 		.binning_factor = 1,
 	},
 };
@@ -349,8 +349,6 @@
 		gain = max_legal_gain;
 	}
 
-	gain = 32;
-	line = 1465;
 	pr_info("s5k4e1_write_exp_gain : gain = %d line = %d\n", gain, line);
 	line = (uint32_t) (line * s_ctrl->fps_divider);
 	fl_lines = s_ctrl->curr_frame_length_lines * s_ctrl->fps_divider / Q10;
@@ -494,6 +492,7 @@
 	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(s5k4e1_subdev_info),
 	.sensor_v4l2_subdev_ops = &s5k4e1_subdev_ops,
 	.func_tbl = &s5k4e1_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
 };
 
 module_init(msm_sensor_init_module);
diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h
index e02597a..cb728a0 100644
--- a/include/media/msm_isp.h
+++ b/include/media/msm_isp.h
@@ -199,6 +199,7 @@
 #define VFE_CMD_SCALE_OUTPUT2_CONFIG                    135
 #define VFE_CMD_CAPTURE_RAW                             136
 #define VFE_CMD_STOP_LIVESHOT                           137
+#define VFE_CMD_RECONFIG_VFE                            138
 
 struct msm_isp_cmd {
 	int32_t  id;