Merge "msm: camera: Reorganize power up functions for sensors" into msm-3.0
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index f30f0bf..cd84722 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -13,9 +13,9 @@
 
 #include <asm/mach-types.h>
 #include <linux/i2c.h>
+#include <linux/gpio.h>
 #include <mach/board.h>
 #include <mach/msm_bus_board.h>
-#include <mach/gpio.h>
 #include <mach/gpiomux.h>
 
 #include "devices.h"
@@ -157,19 +157,6 @@
 
 #ifdef CONFIG_MSM_CAMERA
 
-static uint16_t msm_cam_gpio_2d_tbl[] = {
-	5, /*CAMIF_MCLK*/
-	10, /*CAMIF_I2C_DATA*/
-	11, /*CAMIF_I2C_CLK*/
-};
-
-static struct msm_camera_gpio_conf gpio_conf = {
-	.cam_gpiomux_conf_tbl = apq8064_cam_2d_configs,
-	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(apq8064_cam_2d_configs),
-	.cam_gpio_tbl = msm_cam_gpio_2d_tbl,
-	.cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
-};
-
 static struct msm_bus_vectors cam_init_vectors[] = {
 	{
 		.src = MSM_BUS_MASTER_VFE,
@@ -306,19 +293,57 @@
 
 static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
 	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
 		.csid_core = 0,
+		.is_csiphy = 1,
+		.is_csid   = 1,
+		.is_ispif  = 1,
+		.is_vpe    = 1,
 		.cam_bus_scale_table = &cam_bus_client_pdata,
 	},
 	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
 		.csid_core = 1,
+		.is_csiphy = 1,
+		.is_csid   = 1,
+		.is_ispif  = 1,
+		.is_vpe    = 1,
 		.cam_bus_scale_table = &cam_bus_client_pdata,
 	},
 };
 
+static struct camera_vreg_t msm_8064_back_cam_vreg[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+	{"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
+};
+
+static struct gpio apq8064_common_cam_gpio[] = {
+	{5, GPIOF_DIR_IN, "CAMIF_MCLK"},
+	{20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
+	{21, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
+};
+
+static struct gpio apq8064_back_cam_gpio[] = {
+	{107, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct msm_gpio_set_tbl apq8064_back_cam_gpio_set_tbl[] = {
+	{107, GPIOF_OUT_INIT_LOW, 1000},
+	{107, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_camera_gpio_conf apq8064_back_cam_gpio_conf = {
+	.cam_gpiomux_conf_tbl = apq8064_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(apq8064_cam_2d_configs),
+	.cam_gpio_common_tbl = apq8064_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(apq8064_common_cam_gpio),
+	.cam_gpio_req_tbl = apq8064_back_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(apq8064_back_cam_gpio),
+	.cam_gpio_set_tbl = apq8064_back_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(apq8064_back_cam_gpio_set_tbl),
+};
+
 #ifdef CONFIG_IMX074
 static struct msm_camera_sensor_flash_data flash_imx074 = {
 	.flash_type	= MSM_CAMERA_FLASH_NONE,
@@ -326,10 +351,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
 	.mount_angle	= 90,
-	.sensor_reset	= 107,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 0,
-	.vcm_enable	= 1,
+	.cam_vreg = msm_8064_back_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8064_back_cam_vreg),
+	.gpio_conf = &apq8064_back_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
@@ -337,7 +361,6 @@
 	.pdata	= &msm_camera_csi_device_data[0],
 	.flash_data	= &flash_imx074,
 	.sensor_platform_info = &sensor_board_info_imx074,
-	.gpio_conf = &gpio_conf,
 	.csi_if	= 1,
 	.camera_type = BACK_CAMERA_2D,
 };
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index a32699f..30c912e 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -12,9 +12,9 @@
  */
 
 #include <asm/mach-types.h>
+#include <linux/gpio.h>
 #include <mach/board.h>
 #include <mach/msm_bus_board.h>
-#include <mach/gpio.h>
 #include <mach/gpiomux.h>
 #include "devices.h"
 #include "board-8930.h"
@@ -95,7 +95,7 @@
 };
 
 
-static struct msm_gpiomux_config msm8960_cam_common_configs[] = {
+static struct msm_gpiomux_config msm8930_cam_common_configs[] = {
 	{
 		.gpio = 2,
 		.settings = {
@@ -140,7 +140,7 @@
 	},
 };
 
-static struct msm_gpiomux_config msm8960_cam_2d_configs[] = {
+static struct msm_gpiomux_config msm8930_cam_2d_configs[] = {
 	{
 		.gpio = 18,
 		.settings = {
@@ -172,20 +172,6 @@
 };
 
 #ifdef CONFIG_MSM_CAMERA
-
-static uint16_t msm_cam_gpio_2d_tbl[] = {
-	5, /*CAMIF_MCLK*/
-	20, /*CAMIF_I2C_DATA*/
-	21, /*CAMIF_I2C_CLK*/
-};
-
-static struct msm_camera_gpio_conf gpio_conf = {
-	.cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
-	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
-	.cam_gpio_tbl = msm_cam_gpio_2d_tbl,
-	.cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
-};
-
 #define VFE_CAMIF_TIMER1_GPIO 2
 #define VFE_CAMIF_TIMER2_GPIO 3
 #define VFE_CAMIF_TIMER3_GPIO_INT 4
@@ -345,8 +331,6 @@
 
 static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
 	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
 		.csid_core = 0,
 		.is_csiphy = 1,
 		.is_csid   = 1,
@@ -355,8 +339,6 @@
 		.cam_bus_scale_table = &cam_bus_client_pdata,
 	},
 	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
 		.csid_core = 1,
 		.is_csiphy = 1,
 		.is_csid   = 1,
@@ -366,6 +348,67 @@
 	},
 };
 
+static struct camera_vreg_t msm_8930_back_cam_vreg[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+	{"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
+};
+
+static struct camera_vreg_t msm_8930_front_cam_vreg[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+};
+
+static struct gpio msm8930_common_cam_gpio[] = {
+	{5, GPIOF_DIR_IN, "CAMIF_MCLK"},
+	{20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
+	{21, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
+};
+
+static struct gpio msm8930_front_cam_gpio[] = {
+	{76, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct gpio msm8930_back_cam_gpio[] = {
+	{107, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct msm_gpio_set_tbl msm8930_front_cam_gpio_set_tbl[] = {
+	{76, GPIOF_OUT_INIT_LOW, 1000},
+	{76, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_gpio_set_tbl msm8930_back_cam_gpio_set_tbl[] = {
+	{107, GPIOF_OUT_INIT_LOW, 1000},
+	{107, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_camera_gpio_conf msm_8930_front_cam_gpio_conf = {
+	.cam_gpiomux_conf_tbl = msm8930_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8930_cam_2d_configs),
+	.cam_gpio_common_tbl = msm8930_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(msm8930_common_cam_gpio),
+	.cam_gpio_req_tbl = msm8930_front_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(msm8930_front_cam_gpio),
+	.cam_gpio_set_tbl = msm8930_front_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8930_front_cam_gpio_set_tbl),
+};
+
+static struct msm_camera_gpio_conf msm_8930_back_cam_gpio_conf = {
+	.cam_gpiomux_conf_tbl = msm8930_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8930_cam_2d_configs),
+	.cam_gpio_common_tbl = msm8930_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(msm8930_common_cam_gpio),
+	.cam_gpio_req_tbl = msm8930_back_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(msm8930_back_cam_gpio),
+	.cam_gpio_set_tbl = msm8930_back_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8930_back_cam_gpio_set_tbl),
+};
+
 #ifdef CONFIG_IMX074_ACT
 static struct i2c_board_info imx074_actuator_i2c_info = {
 	I2C_BOARD_INFO("imx074_act", 0x11),
@@ -389,10 +432,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
 	.mount_angle	= 90,
-	.sensor_reset	= 107,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 0,
-	.vcm_enable	= 1,
+	.cam_vreg = msm_8930_back_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8930_back_cam_vreg),
+	.gpio_conf = &msm_8930_back_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
@@ -401,7 +443,6 @@
 	.flash_data	= &flash_imx074,
 	.strobe_flash_data = &strobe_flash_xenon,
 	.sensor_platform_info = &sensor_board_info_imx074,
-	.gpio_conf = &gpio_conf,
 	.csi_if	= 1,
 	.camera_type = BACK_CAMERA_2D,
 #ifdef CONFIG_IMX074_ACT
@@ -417,7 +458,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
 	.mount_angle = 90,
-	.sensor_reset = 107,
+	.cam_vreg = msm_8930_back_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8930_back_cam_vreg),
+	.gpio_conf = &msm_8930_back_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_mt9m114_data = {
@@ -425,7 +468,6 @@
 	.pdata = &msm_camera_csi_device_data[0],
 	.flash_data = &flash_mt9m114,
 	.sensor_platform_info = &sensor_board_info_mt9m114,
-	.gpio_conf = &gpio_conf,
 	.csi_if = 1,
 	.camera_type = BACK_CAMERA_2D,
 };
@@ -438,10 +480,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
 	.mount_angle	= 0,
-	.sensor_reset	= 76,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 0,
-	.vcm_enable	= 1,
+	.cam_vreg = msm_8930_front_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8930_front_cam_vreg),
+	.gpio_conf = &msm_8930_front_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_ov2720_data = {
@@ -449,7 +490,6 @@
 	.pdata	= &msm_camera_csi_device_data[1],
 	.flash_data	= &flash_ov2720,
 	.sensor_platform_info = &sensor_board_info_ov2720,
-	.gpio_conf = &gpio_conf,
 	.csi_if	= 1,
 	.camera_type = FRONT_CAMERA_2D,
 };
@@ -457,8 +497,8 @@
 
 void __init msm8930_init_cam(void)
 {
-	msm_gpiomux_install(msm8960_cam_common_configs,
-			ARRAY_SIZE(msm8960_cam_common_configs));
+	msm_gpiomux_install(msm8930_cam_common_configs,
+			ARRAY_SIZE(msm8930_cam_common_configs));
 
 	platform_device_register(&msm8960_device_csiphy0);
 	platform_device_register(&msm8960_device_csiphy1);
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index 2ad92b3..2995679 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -12,9 +12,9 @@
  */
 
 #include <asm/mach-types.h>
+#include <linux/gpio.h>
 #include <mach/board.h>
 #include <mach/msm_bus_board.h>
-#include <mach/gpio.h>
 #include <mach/gpiomux.h>
 #include "devices.h"
 #include "board-8960.h"
@@ -181,20 +181,6 @@
 };
 
 #ifdef CONFIG_MSM_CAMERA
-
-static uint16_t msm_cam_gpio_2d_tbl[] = {
-	5, /*CAMIF_MCLK*/
-	20, /*CAMIF_I2C_DATA*/
-	21, /*CAMIF_I2C_CLK*/
-};
-
-static struct msm_camera_gpio_conf gpio_conf = {
-	.cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
-	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
-	.cam_gpio_tbl = msm_cam_gpio_2d_tbl,
-	.cam_gpio_tbl_size = ARRAY_SIZE(msm_cam_gpio_2d_tbl),
-};
-
 #define VFE_CAMIF_TIMER1_GPIO 2
 #define VFE_CAMIF_TIMER2_GPIO 3
 #define VFE_CAMIF_TIMER3_GPIO_INT 4
@@ -350,8 +336,6 @@
 
 static struct msm_camera_device_platform_data msm_camera_csi_device_data[] = {
 	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
 		.csid_core = 0,
 		.is_csiphy = 1,
 		.is_csid   = 1,
@@ -360,8 +344,6 @@
 		.cam_bus_scale_table = &cam_bus_client_pdata,
 	},
 	{
-		.ioclk.mclk_clk_rate = 24000000,
-		.ioclk.vfe_clk_rate  = 228570000,
 		.csid_core = 1,
 		.is_csiphy = 1,
 		.is_csid   = 1,
@@ -371,6 +353,67 @@
 	},
 };
 
+static struct camera_vreg_t msm_8960_back_cam_vreg[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_VS, 0, 0, 0},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+	{"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
+};
+
+static struct camera_vreg_t msm_8960_front_cam_vreg[] = {
+	{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+	{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+	{"cam_vio", REG_VS, 0, 0, 0},
+	{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+};
+
+static struct gpio msm8960_common_cam_gpio[] = {
+	{5, GPIOF_DIR_IN, "CAMIF_MCLK"},
+	{20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
+	{21, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
+};
+
+static struct gpio msm8960_front_cam_gpio[] = {
+	{76, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct gpio msm8960_back_cam_gpio[] = {
+	{107, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct msm_gpio_set_tbl msm8960_front_cam_gpio_set_tbl[] = {
+	{76, GPIOF_OUT_INIT_LOW, 1000},
+	{76, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_gpio_set_tbl msm8960_back_cam_gpio_set_tbl[] = {
+	{107, GPIOF_OUT_INIT_LOW, 1000},
+	{107, GPIOF_OUT_INIT_HIGH, 4000},
+};
+
+static struct msm_camera_gpio_conf msm_8960_front_cam_gpio_conf = {
+	.cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
+	.cam_gpio_common_tbl = msm8960_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(msm8960_common_cam_gpio),
+	.cam_gpio_req_tbl = msm8960_front_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(msm8960_front_cam_gpio),
+	.cam_gpio_set_tbl = msm8960_front_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8960_front_cam_gpio_set_tbl),
+};
+
+static struct msm_camera_gpio_conf msm_8960_back_cam_gpio_conf = {
+	.cam_gpiomux_conf_tbl = msm8960_cam_2d_configs,
+	.cam_gpiomux_conf_tbl_size = ARRAY_SIZE(msm8960_cam_2d_configs),
+	.cam_gpio_common_tbl = msm8960_common_cam_gpio,
+	.cam_gpio_common_tbl_size = ARRAY_SIZE(msm8960_common_cam_gpio),
+	.cam_gpio_req_tbl = msm8960_back_cam_gpio,
+	.cam_gpio_req_tbl_size = ARRAY_SIZE(msm8960_back_cam_gpio),
+	.cam_gpio_set_tbl = msm8960_back_cam_gpio_set_tbl,
+	.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8960_back_cam_gpio_set_tbl),
+};
+
 #ifdef CONFIG_IMX074_ACT
 static struct i2c_board_info imx074_actuator_i2c_info = {
 	I2C_BOARD_INFO("imx074_act", 0x11),
@@ -394,10 +437,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
 	.mount_angle	= 90,
-	.sensor_reset	= 107,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 0,
-	.vcm_enable	= 1,
+	.cam_vreg = msm_8960_back_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8960_back_cam_vreg),
+	.gpio_conf = &msm_8960_back_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
@@ -406,7 +448,6 @@
 	.flash_data	= &flash_imx074,
 	.strobe_flash_data = &strobe_flash_xenon,
 	.sensor_platform_info = &sensor_board_info_imx074,
-	.gpio_conf = &gpio_conf,
 	.csi_if	= 1,
 	.camera_type = BACK_CAMERA_2D,
 #ifdef CONFIG_IMX074_ACT
@@ -422,7 +463,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
 	.mount_angle = 90,
-	.sensor_reset = 107,
+	.cam_vreg = msm_8960_back_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8960_back_cam_vreg),
+	.gpio_conf = &msm_8960_back_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_mt9m114_data = {
@@ -430,7 +473,6 @@
 	.pdata = &msm_camera_csi_device_data[0],
 	.flash_data = &flash_mt9m114,
 	.sensor_platform_info = &sensor_board_info_mt9m114,
-	.gpio_conf = &gpio_conf,
 	.csi_if = 1,
 	.camera_type = BACK_CAMERA_2D,
 };
@@ -443,10 +485,9 @@
 
 static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
 	.mount_angle	= 0,
-	.sensor_reset	= 76,
-	.sensor_pwd	= 85,
-	.vcm_pwd	= 0,
-	.vcm_enable	= 1,
+	.cam_vreg = msm_8960_front_cam_vreg,
+	.num_vreg = ARRAY_SIZE(msm_8960_front_cam_vreg),
+	.gpio_conf = &msm_8960_front_cam_gpio_conf,
 };
 
 static struct msm_camera_sensor_info msm_camera_sensor_ov2720_data = {
@@ -454,16 +495,36 @@
 	.pdata	= &msm_camera_csi_device_data[1],
 	.flash_data	= &flash_ov2720,
 	.sensor_platform_info = &sensor_board_info_ov2720,
-	.gpio_conf = &gpio_conf,
 	.csi_if	= 1,
 	.camera_type = FRONT_CAMERA_2D,
 };
 #endif
 
-static struct msm8960_privacy_light_cfg privacy_light_info = {
-	.mpp = PM8921_MPP_PM_TO_SYS(12),
+static struct pm8xxx_mpp_config_data privacy_light_on_config = {
+	.type		= PM8XXX_MPP_TYPE_SINK,
+	.level		= PM8XXX_MPP_CS_OUT_5MA,
+	.control	= PM8XXX_MPP_CS_CTRL_MPP_LOW_EN,
 };
 
+static struct pm8xxx_mpp_config_data privacy_light_off_config = {
+	.type		= PM8XXX_MPP_TYPE_SINK,
+	.level		= PM8XXX_MPP_CS_OUT_5MA,
+	.control	= PM8XXX_MPP_CS_CTRL_DISABLE,
+};
+
+static int32_t msm_camera_8960_ext_power_ctrl(int enable)
+{
+	int rc = 0;
+	if (enable) {
+		rc = pm8xxx_mpp_config(PM8921_MPP_PM_TO_SYS(12),
+			&privacy_light_on_config);
+	} else {
+		rc = pm8xxx_mpp_config(PM8921_MPP_PM_TO_SYS(12),
+			&privacy_light_off_config);
+	}
+	return rc;
+}
+
 void __init msm8960_init_cam(void)
 {
 	msm_gpiomux_install(msm8960_cam_common_configs,
@@ -488,9 +549,8 @@
 		s_info = &msm_camera_sensor_imx074_data;
 		s_info->sensor_platform_info->mount_angle = 180;
 		s_info = &msm_camera_sensor_ov2720_data;
-		s_info->sensor_platform_info->privacy_light = 1;
-		s_info->sensor_platform_info->privacy_light_info =
-			&privacy_light_info;
+		s_info->sensor_platform_info->ext_power_ctrl =
+			msm_camera_8960_ext_power_ctrl;
 	}
 
 	platform_device_register(&msm8960_device_csiphy0);
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index d11c13f..76b7dac 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -172,26 +172,43 @@
 	BACK_CAMERA_INT_3D,
 };
 
-struct msm8960_privacy_light_cfg {
-	unsigned mpp;
+enum camera_vreg_type {
+	REG_LDO,
+	REG_VS,
 };
 
-struct msm_camera_sensor_platform_info {
-	int mount_angle;
-	int sensor_reset_enable;
-	int sensor_reset;
-	int sensor_pwd;
-	int vcm_pwd;
-	int vcm_enable;
-	int privacy_light;
-	void *privacy_light_info;
+struct camera_vreg_t {
+	char *reg_name;
+	enum camera_vreg_type type;
+	int min_voltage;
+	int max_voltage;
+	int op_mode;
+};
+
+struct msm_gpio_set_tbl {
+	unsigned gpio;
+	unsigned long flags;
+	uint32_t delay;
 };
 
 struct msm_camera_gpio_conf {
 	void *cam_gpiomux_conf_tbl;
 	uint8_t cam_gpiomux_conf_tbl_size;
-	uint16_t *cam_gpio_tbl;
-	uint8_t cam_gpio_tbl_size;
+	struct gpio *cam_gpio_common_tbl;
+	uint8_t cam_gpio_common_tbl_size;
+	struct gpio *cam_gpio_req_tbl;
+	uint8_t cam_gpio_req_tbl_size;
+	struct msm_gpio_set_tbl *cam_gpio_set_tbl;
+	uint8_t cam_gpio_set_tbl_size;
+};
+
+struct msm_camera_sensor_platform_info {
+	int mount_angle;
+	int sensor_reset;
+	struct camera_vreg_t *cam_vreg;
+	int num_vreg;
+	int32_t (*ext_power_ctrl) (int enable);
+	struct msm_camera_gpio_conf *gpio_conf;
 };
 
 struct msm_actuator_info {
@@ -219,7 +236,6 @@
 	struct msm_camera_csi_params csi_params;
 	struct msm_camera_sensor_strobe_flash_data *strobe_flash_data;
 	char *eeprom_data;
-	struct msm_camera_gpio_conf *gpio_conf;
 	enum msm_camera_type camera_type;
 	struct msm_actuator_info *actuator_info;
 };
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 1abfd7b..8c61a42 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -19,6 +19,7 @@
 #include <linux/cdev.h>
 #include <linux/platform_device.h>
 #include <linux/wakelock.h>
+#include <linux/regulator/consumer.h>
 #include "linux/types.h"
 
 #include <mach/board.h>
@@ -687,7 +688,15 @@
 
 int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
 		struct clk **clk_ptr, int num_clk, int enable);
-int msm_sensor_probe_on(struct device *);
-int msm_sensor_probe_off(struct device *);
 int msm_cam_core_reset(void);
+
+int msm_camera_config_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+		int num_vreg, struct regulator **reg_ptr, int config);
+int msm_camera_enable_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+		int num_vreg, struct regulator **reg_ptr, int enable);
+
+int msm_camera_config_gpio_table
+	(struct msm_camera_sensor_info *sinfo, int gpio_en);
+int msm_camera_request_gpio_table
+	(struct msm_camera_sensor_info *sinfo, int gpio_en);
 #endif
diff --git a/drivers/media/video/msm/io/msm_io_util.c b/drivers/media/video/msm/io/msm_io_util.c
index 9f58d6e..0ae247e 100644
--- a/drivers/media/video/msm/io/msm_io_util.c
+++ b/drivers/media/video/msm/io/msm_io_util.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
@@ -12,8 +12,11 @@
 
 #include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
 #include <mach/board.h>
 #include <mach/camera.h>
+#include <mach/gpiomux.h>
 
 int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
 		struct clk **clk_ptr, int num_clk, int enable)
@@ -66,3 +69,183 @@
 	return rc;
 }
 
+int msm_camera_config_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+		int num_vreg, struct regulator **reg_ptr, int config)
+{
+	int i = 0;
+	int rc = 0;
+	struct camera_vreg_t *curr_vreg;
+	if (config) {
+		for (i = 0; i < num_vreg; i++) {
+			curr_vreg = &cam_vreg[i];
+			reg_ptr[i] = regulator_get(dev,
+				curr_vreg->reg_name);
+			if (IS_ERR(reg_ptr[i])) {
+				pr_err("%s: %s get failed\n",
+				 __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);
+				if (rc < 0) {
+					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;
+				}
+			}
+		}
+	} else {
+		for (i = num_vreg-1; i >= 0; i--) {
+			curr_vreg = &cam_vreg[i];
+			if (reg_ptr[i]) {
+				if (curr_vreg->type == REG_LDO) {
+					regulator_set_optimum_mode(
+						reg_ptr[i], 0);
+					regulator_set_voltage(
+						reg_ptr[i],
+						0, curr_vreg->max_voltage);
+				}
+				regulator_put(reg_ptr[i]);
+				reg_ptr[i] = NULL;
+			}
+		}
+	}
+	return 0;
+
+vreg_unconfig:
+if (curr_vreg->type == REG_LDO)
+	regulator_set_optimum_mode(reg_ptr[i], 0);
+
+vreg_set_opt_mode_fail:
+if (curr_vreg->type == REG_LDO)
+	regulator_set_voltage(reg_ptr[i], 0,
+		curr_vreg->max_voltage);
+
+vreg_set_voltage_fail:
+	regulator_put(reg_ptr[i]);
+	reg_ptr[i] = NULL;
+
+vreg_get_fail:
+	for (i--; i >= 0; i--) {
+		curr_vreg = &cam_vreg[i];
+		goto vreg_unconfig;
+	}
+	return -ENODEV;
+}
+
+int msm_camera_enable_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
+		int num_vreg, struct regulator **reg_ptr, int enable)
+{
+	int i = 0, rc = 0;
+	if (enable) {
+		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);
+				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);
+				goto disable_vreg;
+			}
+		}
+	} else {
+		for (i = num_vreg-1; i >= 0; i--)
+			regulator_disable(reg_ptr[i]);
+	}
+	return rc;
+disable_vreg:
+	for (i--; i >= 0; i--) {
+		regulator_disable(reg_ptr[i]);
+		goto disable_vreg;
+	}
+	return rc;
+}
+
+int msm_camera_request_gpio_table(struct msm_camera_sensor_info *sinfo,
+	int gpio_en)
+{
+	int rc = 0;
+	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_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,
+				gpio_conf->cam_gpio_common_tbl_size);
+		if (rc < 0) {
+			pr_err("%s common gpio request failed\n", __func__);
+			return rc;
+		}
+		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;
+		}
+	} 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);
+	}
+	return rc;
+}
+
+int msm_camera_config_gpio_table(struct msm_camera_sensor_info *sinfo,
+	int gpio_en)
+{
+	struct msm_camera_gpio_conf *gpio_conf =
+		sinfo->sensor_platform_info->gpio_conf;
+	int rc = 0, i;
+
+	if (gpio_en) {
+		for (i = 0; i < gpio_conf->cam_gpio_set_tbl_size; i++) {
+			gpio_set_value_cansleep(
+				gpio_conf->cam_gpio_set_tbl[i].gpio,
+				gpio_conf->cam_gpio_set_tbl[i].flags);
+			usleep_range(gpio_conf->cam_gpio_set_tbl[i].delay,
+				gpio_conf->cam_gpio_set_tbl[i].delay + 1000);
+		}
+	} else {
+		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(
+					gpio_conf->cam_gpio_set_tbl[i].gpio,
+					GPIOF_OUT_INIT_LOW);
+		}
+	}
+	return rc;
+}
diff --git a/drivers/media/video/msm/msm_io_8960.c b/drivers/media/video/msm/msm_io_8960.c
index f35b5f1..79294a3 100644
--- a/drivers/media/video/msm/msm_io_8960.c
+++ b/drivers/media/video/msm/msm_io_8960.c
@@ -27,38 +27,14 @@
 
 #define BUFF_SIZE_128 128
 
-#define CAM_VAF_MINUV                 2800000
-#define CAM_VAF_MAXUV                 2800000
-#define CAM_VDIG_MINUV                    1200000
-#define CAM_VDIG_MAXUV                    1200000
-#define CAM_VANA_MINUV                    2800000
-#define CAM_VANA_MAXUV                    2850000
-#define CAM_CSI_VDD_MINUV                  1200000
-#define CAM_CSI_VDD_MAXUV                  1200000
-
-#define CAM_VAF_LOAD_UA               300000
-#define CAM_VDIG_LOAD_UA                  105000
-#define CAM_VANA_LOAD_UA                  85600
-#define CAM_CSI_LOAD_UA                    20000
-
-static struct clk *camio_cam_clk;
-
 static struct clk *camio_jpeg_clk;
 static struct clk *camio_jpeg_pclk;
 static struct regulator *fs_ijpeg;
-static struct regulator *cam_vana;
-static struct regulator *cam_vio;
-static struct regulator *cam_vdig;
-static struct regulator *cam_vaf;
-static struct regulator *mipi_csi_vdd;
 
-static struct msm_camera_io_clk camio_clk;
 static struct platform_device *camio_dev;
 static struct resource *s3drw_io, *s3dctl_io;
 static struct resource *s3drw_mem, *s3dctl_mem;
 void __iomem *s3d_rw, *s3d_ctl;
-struct msm_bus_scale_pdata *cam_bus_scale_table;
-
 
 void msm_io_w(u32 data, void __iomem *addr)
 {
@@ -136,213 +112,12 @@
 	msm_io_dump(dest_addr, len);
 }
 
-static int msm_camera_vreg_enable(struct device *dev)
-{
-	if (mipi_csi_vdd == NULL) {
-		mipi_csi_vdd = regulator_get(dev, "mipi_csi_vdd");
-		if (IS_ERR(mipi_csi_vdd)) {
-			CDBG("%s: VREG MIPI CSI VDD get failed\n", __func__);
-			mipi_csi_vdd = NULL;
-			return -ENODEV;
-		}
-		if (regulator_set_voltage(mipi_csi_vdd, CAM_CSI_VDD_MINUV,
-			CAM_CSI_VDD_MAXUV)) {
-			CDBG("%s: VREG MIPI CSI VDD set voltage failed\n",
-				__func__);
-			goto mipi_csi_vdd_put;
-		}
-		if (regulator_set_optimum_mode(mipi_csi_vdd,
-			CAM_CSI_LOAD_UA) < 0) {
-			CDBG("%s: VREG MIPI CSI set optimum mode failed\n",
-				__func__);
-			goto mipi_csi_vdd_release;
-		}
-		if (regulator_enable(mipi_csi_vdd)) {
-			CDBG("%s: VREG MIPI CSI VDD enable failed\n",
-				__func__);
-			goto mipi_csi_vdd_disable;
-		}
-	}
-	if (cam_vana == NULL) {
-		cam_vana = regulator_get(dev, "cam_vana");
-		if (IS_ERR(cam_vana)) {
-			CDBG("%s: VREG CAM VANA get failed\n", __func__);
-			cam_vana = NULL;
-			goto mipi_csi_vdd_disable;
-		}
-		if (regulator_set_voltage(cam_vana, CAM_VANA_MINUV,
-			CAM_VANA_MAXUV)) {
-			CDBG("%s: VREG CAM VANA set voltage failed\n",
-				__func__);
-			goto cam_vana_put;
-		}
-		if (regulator_set_optimum_mode(cam_vana,
-			CAM_VANA_LOAD_UA) < 0) {
-			CDBG("%s: VREG CAM VANA set optimum mode failed\n",
-				__func__);
-			goto cam_vana_release;
-		}
-		if (regulator_enable(cam_vana)) {
-			CDBG("%s: VREG CAM VANA enable failed\n", __func__);
-			goto cam_vana_disable;
-		}
-	}
-	if (cam_vio == NULL) {
-		cam_vio = regulator_get(dev, "cam_vio");
-		if (IS_ERR(cam_vio)) {
-			CDBG("%s: VREG VIO get failed\n", __func__);
-			cam_vio = NULL;
-			goto cam_vana_disable;
-		}
-		if (regulator_enable(cam_vio)) {
-			CDBG("%s: VREG VIO enable failed\n", __func__);
-			goto cam_vio_put;
-		}
-	}
-	if (cam_vdig == NULL) {
-		cam_vdig = regulator_get(dev, "cam_vdig");
-		if (IS_ERR(cam_vdig)) {
-			CDBG("%s: VREG CAM VDIG get failed\n", __func__);
-			cam_vdig = NULL;
-			goto cam_vio_disable;
-		}
-		if (regulator_set_voltage(cam_vdig, CAM_VDIG_MINUV,
-			CAM_VDIG_MAXUV)) {
-			CDBG("%s: VREG CAM VDIG set voltage failed\n",
-				__func__);
-			goto cam_vdig_put;
-		}
-		if (regulator_set_optimum_mode(cam_vdig,
-			CAM_VDIG_LOAD_UA) < 0) {
-			CDBG("%s: VREG CAM VDIG set optimum mode failed\n",
-				__func__);
-			goto cam_vdig_release;
-		}
-		if (regulator_enable(cam_vdig)) {
-			CDBG("%s: VREG CAM VDIG enable failed\n", __func__);
-			goto cam_vdig_disable;
-		}
-	}
-	if (cam_vaf == NULL) {
-		cam_vaf = regulator_get(dev, "cam_vaf");
-		if (IS_ERR(cam_vaf)) {
-			CDBG("%s: VREG CAM VAF get failed\n", __func__);
-			cam_vaf = NULL;
-			goto cam_vdig_disable;
-		}
-		if (regulator_set_voltage(cam_vaf, CAM_VAF_MINUV,
-			CAM_VAF_MAXUV)) {
-			CDBG("%s: VREG CAM VAF set voltage failed\n",
-				__func__);
-			goto cam_vaf_put;
-		}
-		if (regulator_set_optimum_mode(cam_vaf,
-			CAM_VAF_LOAD_UA) < 0) {
-			CDBG("%s: VREG CAM VAF set optimum mode failed\n",
-				__func__);
-			goto cam_vaf_release;
-		}
-		if (regulator_enable(cam_vaf)) {
-			CDBG("%s: VREG CAM VAF enable failed\n", __func__);
-			goto cam_vaf_disable;
-		}
-	}
-	return 0;
-
-cam_vaf_disable:
-	regulator_set_optimum_mode(cam_vaf, 0);
-cam_vaf_release:
-	regulator_set_voltage(cam_vaf, 0, CAM_VAF_MAXUV);
-	regulator_disable(cam_vaf);
-cam_vaf_put:
-	regulator_put(cam_vaf);
-	cam_vaf = NULL;
-cam_vdig_disable:
-	regulator_set_optimum_mode(cam_vdig, 0);
-cam_vdig_release:
-	regulator_set_voltage(cam_vdig, 0, CAM_VDIG_MAXUV);
-	regulator_disable(cam_vdig);
-cam_vdig_put:
-	regulator_put(cam_vdig);
-	cam_vdig = NULL;
-cam_vio_disable:
-	regulator_disable(cam_vio);
-cam_vio_put:
-	regulator_put(cam_vio);
-	cam_vio = NULL;
-cam_vana_disable:
-	regulator_set_optimum_mode(cam_vana, 0);
-cam_vana_release:
-	regulator_set_voltage(cam_vana, 0, CAM_VANA_MAXUV);
-	regulator_disable(cam_vana);
-cam_vana_put:
-	regulator_put(cam_vana);
-	cam_vana = NULL;
-mipi_csi_vdd_disable:
-	regulator_set_optimum_mode(mipi_csi_vdd, 0);
-mipi_csi_vdd_release:
-	regulator_set_voltage(mipi_csi_vdd, 0, CAM_CSI_VDD_MAXUV);
-	regulator_disable(mipi_csi_vdd);
-
-mipi_csi_vdd_put:
-	regulator_put(mipi_csi_vdd);
-	mipi_csi_vdd = NULL;
-	return -ENODEV;
-}
-
-static void msm_camera_vreg_disable(void)
-{
-	if (mipi_csi_vdd) {
-		regulator_set_voltage(mipi_csi_vdd, 0, CAM_CSI_VDD_MAXUV);
-		regulator_set_optimum_mode(mipi_csi_vdd, 0);
-		regulator_disable(mipi_csi_vdd);
-		regulator_put(mipi_csi_vdd);
-		mipi_csi_vdd = NULL;
-	}
-
-	if (cam_vana) {
-		regulator_set_voltage(cam_vana, 0, CAM_VANA_MAXUV);
-		regulator_set_optimum_mode(cam_vana, 0);
-		regulator_disable(cam_vana);
-		regulator_put(cam_vana);
-		cam_vana = NULL;
-	}
-
-	if (cam_vio) {
-		regulator_disable(cam_vio);
-		regulator_put(cam_vio);
-		cam_vio = NULL;
-	}
-
-	if (cam_vdig) {
-		regulator_set_voltage(cam_vdig, 0, CAM_VDIG_MAXUV);
-		regulator_set_optimum_mode(cam_vdig, 0);
-		regulator_disable(cam_vdig);
-		regulator_put(cam_vdig);
-		cam_vdig = NULL;
-	}
-
-	if (cam_vaf) {
-		regulator_set_voltage(cam_vaf, 0, CAM_VAF_MAXUV);
-		regulator_set_optimum_mode(cam_vaf, 0);
-		regulator_disable(cam_vaf);
-		regulator_put(cam_vaf);
-		cam_vaf = NULL;
-	}
-}
-
 int msm_camio_clk_enable(enum msm_camio_clk_type clktype)
 {
 	int rc = 0;
 	struct clk *clk = NULL;
 
 	switch (clktype) {
-	case CAMIO_CAM_MCLK_CLK:
-		camio_cam_clk =
-		clk = clk_get(&camio_dev->dev, "cam_clk");
-		msm_camio_clk_rate_set_2(clk, camio_clk.mclk_clk_rate);
-		break;
-
 	case CAMIO_JPEG_CLK:
 		camio_jpeg_clk =
 		clk = clk_get(NULL, "ijpeg_clk");
@@ -375,10 +150,6 @@
 	struct clk *clk = NULL;
 
 	switch (clktype) {
-	case CAMIO_CAM_MCLK_CLK:
-		clk = camio_cam_clk;
-		break;
-
 	case CAMIO_JPEG_CLK:
 		clk = camio_jpeg_clk;
 		break;
@@ -403,12 +174,6 @@
 	return rc;
 }
 
-void msm_camio_clk_rate_set(int rate)
-{
-	struct clk *clk = camio_cam_clk;
-	clk_set_rate(clk, rate);
-}
-
 void msm_camio_clk_rate_set_2(struct clk *clk, int rate)
 {
 	clk_set_rate(clk, rate);
@@ -459,38 +224,6 @@
 	return rc;
 }
 
-static int config_gpio_table(struct msm_camera_sensor_info *sinfo, int gpio_en)
-{
-	struct msm_camera_gpio_conf *gpio_conf = sinfo->gpio_conf;
-	int rc = 0, i = 0;
-
-	if (gpio_conf->cam_gpio_tbl == NULL || gpio_conf->cam_gpiomux_conf_tbl
-		== NULL) {
-		pr_err("%s: Invalid NULL cam gpio config table\n", __func__);
-		return -EFAULT;
-	}
-
-	if (gpio_en) {
-		msm_gpiomux_install((struct msm_gpiomux_config *)gpio_conf->
-			cam_gpiomux_conf_tbl,
-			gpio_conf->cam_gpiomux_conf_tbl_size);
-		for (i = 0; i < gpio_conf->cam_gpio_tbl_size; i++) {
-			rc = gpio_request(gpio_conf->cam_gpio_tbl[i],
-				 "CAM_GPIO");
-			if (rc < 0) {
-				pr_err("%s not able to get gpio\n", __func__);
-				for (i--; i >= 0; i--)
-					gpio_free(gpio_conf->cam_gpio_tbl[i]);
-					break;
-			}
-		}
-	} else {
-		for (i = 0; i < gpio_conf->cam_gpio_tbl_size; i++)
-			gpio_free(gpio_conf->cam_gpio_tbl[i]);
-	}
-	return rc;
-}
-
 int32_t msm_camio_3d_enable(const struct msm_camera_sensor_info *s_info)
 {
 	int32_t val = 0, rc = 0;
@@ -557,61 +290,6 @@
 	release_mem_region(s3drw_mem->start, resource_size(s3drw_mem));
 }
 
-static struct pm8xxx_mpp_config_data privacy_light_on_config = {
-	.type		= PM8XXX_MPP_TYPE_SINK,
-	.level		= PM8XXX_MPP_CS_OUT_5MA,
-	.control	= PM8XXX_MPP_CS_CTRL_MPP_LOW_EN,
-};
-
-static struct pm8xxx_mpp_config_data privacy_light_off_config = {
-	.type		= PM8XXX_MPP_TYPE_SINK,
-	.level		= PM8XXX_MPP_CS_OUT_5MA,
-	.control	= PM8XXX_MPP_CS_CTRL_DISABLE,
-};
-
-static struct msm_cam_clk_info cam_clk_info[] = {
-	{"cam_clk", 24000000},
-};
-
-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 = config_gpio_table(sinfo, 1);
-	if (rc < 0)
-		return rc;
-	msm_camera_vreg_enable(dev);
-	if (sinfo->sensor_platform_info->privacy_light) {
-		struct msm8960_privacy_light_cfg *privacy_light_config =
-			sinfo->sensor_platform_info->privacy_light_info;
-		pm8xxx_mpp_config(privacy_light_config->mpp,
-						  &privacy_light_on_config);
-	}
-	return msm_cam_clk_enable(dev, cam_clk_info,
-		&camio_cam_clk, ARRAY_SIZE(cam_clk_info), 1);
-}
-
-int msm_sensor_probe_off(struct device *dev)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = dev->platform_data;
-	if (sinfo->sensor_platform_info->privacy_light) {
-		struct msm8960_privacy_light_cfg *privacy_light_config =
-			sinfo->sensor_platform_info->privacy_light_info;
-		pm8xxx_mpp_config(privacy_light_config->mpp,
-						  &privacy_light_off_config);
-	}
-	msm_camera_vreg_disable();
-	rc = config_gpio_table(sinfo, 0);
-	if (rc < 0)
-		return rc;
-	return msm_cam_clk_enable(dev, cam_clk_info,
-		&camio_cam_clk, ARRAY_SIZE(cam_clk_info), 0);
-}
-
 void msm_camio_mode_config(enum msm_cam_mode mode)
 {
 	uint32_t val;
diff --git a/drivers/media/video/msm/sensors/imx074_v4l2.c b/drivers/media/video/msm/sensors/imx074_v4l2.c
index c77cfc3..f31aece 100644
--- a/drivers/media/video/msm/sensors/imx074_v4l2.c
+++ b/drivers/media/video/msm/sensors/imx074_v4l2.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
@@ -331,6 +331,7 @@
 	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(imx074_subdev_info),
 	.sensor_v4l2_subdev_ops = &imx074_subdev_ops,
 	.func_tbl = &imx074_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
 };
 
 module_init(msm_sensor_init_module);
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 227e606..2c296618 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -445,26 +445,84 @@
 	return rc;
 }
 
+static struct msm_cam_clk_info cam_clk_info[] = {
+	{"cam_clk", MSM_SENSOR_MCLK_24HZ},
+};
+
 int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
 {
 	int32_t rc = 0;
 	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
 	CDBG("%s: %d\n", __func__, __LINE__);
-	msm_sensor_probe_on(&s_ctrl->sensor_i2c_client->client->dev);
-	msm_camio_clk_rate_set(MSM_SENSOR_MCLK_24HZ);
-	rc = gpio_request(data->sensor_platform_info->sensor_reset,
-		"SENSOR_NAME");
-	if (!rc) {
-		CDBG("%s: reset sensor\n", __func__);
-		gpio_direction_output(data->sensor_platform_info->sensor_reset,
-			 0);
-		usleep_range(1000, 2000);
-		gpio_set_value_cansleep(data->sensor_platform_info->
-			sensor_reset, 1);
-		usleep_range(4000, 5000);
-	} else {
-		CDBG("%s: gpio request fail", __func__);
+	s_ctrl->reg_ptr = kzalloc(sizeof(struct regulator *)
+			* data->sensor_platform_info->num_vreg, GFP_KERNEL);
+	if (!s_ctrl->reg_ptr) {
+		pr_err("%s: could not allocate mem for regulators\n",
+			__func__);
+		return -ENOMEM;
 	}
+
+	rc = msm_camera_request_gpio_table(data, 1);
+	if (rc < 0) {
+		pr_err("%s: request gpio failed\n", __func__);
+		goto request_gpio_failed;
+	}
+
+	rc = msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+			s_ctrl->sensordata->sensor_platform_info->num_vreg,
+			s_ctrl->reg_ptr, 1);
+	if (rc < 0) {
+		pr_err("%s: regulator on failed\n", __func__);
+		goto config_vreg_failed;
+	}
+
+	rc = msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+			s_ctrl->sensordata->sensor_platform_info->num_vreg,
+			s_ctrl->reg_ptr, 1);
+	if (rc < 0) {
+		pr_err("%s: enable regulator failed\n", __func__);
+		goto enable_vreg_failed;
+	}
+
+	rc = msm_camera_config_gpio_table(data, 1);
+	if (rc < 0) {
+		pr_err("%s: config gpio failed\n", __func__);
+		goto config_gpio_failed;
+	}
+
+	if (s_ctrl->clk_rate != 0)
+		cam_clk_info->clk_rate = s_ctrl->clk_rate;
+
+	rc = msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
+		cam_clk_info, &s_ctrl->cam_clk, ARRAY_SIZE(cam_clk_info), 1);
+	if (rc < 0) {
+		pr_err("%s: clk enable failed\n", __func__);
+		goto enable_clk_failed;
+	}
+
+	if (data->sensor_platform_info->ext_power_ctrl != NULL)
+		data->sensor_platform_info->ext_power_ctrl(1);
+
+	return rc;
+enable_clk_failed:
+		msm_camera_config_gpio_table(data, 0);
+config_gpio_failed:
+	msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+			s_ctrl->sensordata->sensor_platform_info->num_vreg,
+			s_ctrl->reg_ptr, 0);
+
+enable_vreg_failed:
+	msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->reg_ptr, 0);
+config_vreg_failed:
+	msm_camera_request_gpio_table(data, 0);
+request_gpio_failed:
+	kfree(s_ctrl->reg_ptr);
 	return rc;
 }
 
@@ -472,10 +530,21 @@
 {
 	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
 	CDBG("%s\n", __func__);
-	msm_sensor_probe_off(&s_ctrl->sensor_i2c_client->client->dev);
-	gpio_set_value_cansleep(data->sensor_platform_info->sensor_reset, 0);
-	usleep_range(1000, 2000);
-	gpio_free(data->sensor_platform_info->sensor_reset);
+	if (data->sensor_platform_info->ext_power_ctrl != NULL)
+		data->sensor_platform_info->ext_power_ctrl(0);
+	msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
+		cam_clk_info, &s_ctrl->cam_clk, ARRAY_SIZE(cam_clk_info), 0);
+	msm_camera_config_gpio_table(data, 0);
+	msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->reg_ptr, 0);
+	msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
+		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
+		s_ctrl->sensordata->sensor_platform_info->num_vreg,
+		s_ctrl->reg_ptr, 0);
+	msm_camera_request_gpio_table(data, 0);
+	kfree(s_ctrl->reg_ptr);
 	return 0;
 }
 
@@ -530,6 +599,10 @@
 	}
 
 	s_ctrl->sensordata = client->dev.platform_data;
+	if (s_ctrl->sensordata == NULL) {
+		pr_err("%s: NULL sensor data\n", __func__);
+		return -EFAULT;
+	}
 
 	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
 	if (rc < 0)
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index ba366e6..2b1be1e 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -166,6 +166,9 @@
 	uint8_t sensor_v4l2_subdev_info_size;
 	struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
 	struct msm_sensor_fn_t *func_tbl;
+	struct regulator **reg_ptr;
+	struct clk *cam_clk;
+	long clk_rate;
 };
 
 void msm_sensor_start_stream(struct msm_sensor_ctrl_t *s_ctrl);
diff --git a/drivers/media/video/msm/sensors/ov2720.c b/drivers/media/video/msm/sensors/ov2720.c
index 6389498..246900e 100644
--- a/drivers/media/video/msm/sensors/ov2720.c
+++ b/drivers/media/video/msm/sensors/ov2720.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
@@ -492,6 +492,7 @@
 	.sensor_v4l2_subdev_info_size = ARRAY_SIZE(ov2720_subdev_info),
 	.sensor_v4l2_subdev_ops = &ov2720_subdev_ops,
 	.func_tbl = &ov2720_func_tbl,
+	.clk_rate = MSM_SENSOR_MCLK_24HZ,
 };
 
 module_init(msm_sensor_init_module);