msm: camera: Convert camera sensors into i2c devices

Convert camera sensors to i2c devices as well as
v4l2 sub-devices.

Change-Id: Iefe7050aec051bb591dfdb26696094cde65b6af0
Signed-off-by: Kevin Chan <ktchan@codeaurora.org>
Signed-off-by: Jignesh Mehta <jigneshm@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index 9161fbf..7edfa9e 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -11,8 +11,6 @@
  *
  */
 
-#include <linux/i2c.h>
-#include <linux/i2c/sx150x.h>
 #include <asm/mach-types.h>
 #include <mach/board.h>
 #include <mach/msm_bus_board.h>
@@ -402,13 +400,6 @@
 	.actuator_info = &imx074_actuator_info
 #endif
 };
-
-static struct platform_device msm8960_camera_sensor_imx074 = {
-	.name	= "msm_camera_imx074",
-	.dev	= {
-		.platform_data = &msm_camera_sensor_imx074_data,
-	},
-};
 #endif
 #ifdef CONFIG_OV2720
 static struct msm_camera_sensor_flash_data flash_ov2720 = {
@@ -432,33 +423,13 @@
 	.csi_if	= 1,
 	.camera_type = FRONT_CAMERA_2D,
 };
-
-static struct platform_device msm8960_camera_sensor_ov2720 = {
-	.name	= "msm_camera_ov2720",
-	.dev	= {
-		.platform_data = &msm_camera_sensor_ov2720_data,
-	},
-};
 #endif
 
 void __init msm8930_init_cam(void)
 {
-	int i;
-	struct platform_device *cam_dev[] = {
-		&msm8960_camera_sensor_imx074,
-		&msm8960_camera_sensor_ov2720,
-	};
-
 	msm_gpiomux_install(msm8960_cam_common_configs,
 			ARRAY_SIZE(msm8960_cam_common_configs));
 
-	for (i = 0; i < ARRAY_SIZE(cam_dev); i++) {
-		struct msm_camera_sensor_info *s_info;
-		s_info = cam_dev[i]->dev.platform_data;
-		msm_get_cam_resources(s_info);
-		platform_device_register(cam_dev[i]);
-	}
-
 	platform_device_register(&msm8960_device_csiphy0);
 	platform_device_register(&msm8960_device_csiphy1);
 	platform_device_register(&msm8960_device_csid0);
@@ -467,4 +438,31 @@
 	platform_device_register(&msm8960_device_vfe);
 	platform_device_register(&msm8960_device_vpe);
 }
+
+#ifdef CONFIG_I2C
+struct i2c_board_info msm8930_camera_i2c_boardinfo[] = {
+#ifdef CONFIG_IMX074
+	{
+	I2C_BOARD_INFO("imx074", 0x1A),
+	.platform_data = &msm_camera_sensor_imx074_data,
+	},
+#endif
+#ifdef CONFIG_OV2720
+	{
+	I2C_BOARD_INFO("ov2720", 0x6C),
+	.platform_data = &msm_camera_sensor_ov2720_data,
+	},
+#endif
+#ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
+	{
+	I2C_BOARD_INFO("sc628a", 0x6E),
+	},
+#endif
+};
+
+struct msm_camera_board_info msm8930_camera_board_info = {
+	.board_info = msm8930_camera_i2c_boardinfo,
+	.num_i2c_board_info = ARRAY_SIZE(msm8930_camera_i2c_boardinfo),
+};
+#endif
 #endif
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index bff699c..6eba2f9 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -1947,6 +1947,14 @@
 #ifdef CONFIG_I2C
 	u8 mach_mask = 0;
 	int i;
+#ifdef CONFIG_MSM_CAMERA
+	struct i2c_registry msm8930_camera_i2c_devices = {
+		I2C_SURF | I2C_FFA | I2C_FLUID | I2C_LIQUID | I2C_RUMI,
+		MSM_8930_GSBI4_QUP_I2C_BUS_ID,
+		msm8930_camera_board_info.board_info,
+		msm8930_camera_board_info.num_i2c_board_info,
+	};
+#endif
 
 	/* Build the matching 'supported_machs' bitmask */
 	if (machine_is_msm8930_cdp() || machine_is_msm8627_cdp())
@@ -1965,6 +1973,12 @@
 						msm8960_i2c_devices[i].info,
 						msm8960_i2c_devices[i].len);
 	}
+#ifdef CONFIG_MSM_CAMERA
+	if (msm8930_camera_i2c_devices.machs & mach_mask)
+		i2c_register_board_info(msm8930_camera_i2c_devices.bus,
+			msm8930_camera_i2c_devices.info,
+			msm8930_camera_i2c_devices.len);
+#endif
 #endif
 }
 
diff --git a/arch/arm/mach-msm/board-8930.h b/arch/arm/mach-msm/board-8930.h
index 61eb408..c81825f 100644
--- a/arch/arm/mach-msm/board-8930.h
+++ b/arch/arm/mach-msm/board-8930.h
@@ -15,6 +15,7 @@
 
 #include <linux/regulator/gpio-regulator.h>
 #include <linux/mfd/pm8xxx/pm8038.h>
+#include <linux/i2c.h>
 #include <linux/i2c/sx150x.h>
 #include <mach/irqs.h>
 #include <mach/rpm-regulator.h>
@@ -89,6 +90,7 @@
 #endif
 
 extern struct sx150x_platform_data msm8930_sx150x_data[];
+extern struct msm_camera_board_info msm8930_camera_board_info;
 void msm8930_init_cam(void);
 void msm8930_init_fb(void);
 void msm8930_init_pmic(void);
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index f84944b..4466872 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -11,8 +11,6 @@
  *
  */
 
-#include <linux/i2c.h>
-#include <linux/i2c/sx150x.h>
 #include <asm/mach-types.h>
 #include <mach/board.h>
 #include <mach/msm_bus_board.h>
@@ -407,13 +405,6 @@
 	.actuator_info = &imx074_actuator_info
 #endif
 };
-
-static struct platform_device msm8960_camera_sensor_imx074 = {
-	.name	= "msm_camera_imx074",
-	.dev	= {
-		.platform_data = &msm_camera_sensor_imx074_data,
-	},
-};
 #endif
 
 #ifdef CONFIG_MT9M114
@@ -435,13 +426,6 @@
 	.csi_if = 1,
 	.camera_type = BACK_CAMERA_2D,
 };
-
-struct platform_device msm8960_camera_sensor_mt9m114 = {
-	.name = "msm_camera_mt9m114",
-	.dev = {
-		.platform_data = &msm_camera_sensor_mt9m114_data,
-	},
-};
 #endif
 
 #ifdef CONFIG_OV2720
@@ -466,13 +450,6 @@
 	.csi_if	= 1,
 	.camera_type = FRONT_CAMERA_2D,
 };
-
-static struct platform_device msm8960_camera_sensor_ov2720 = {
-	.name	= "msm_camera_ov2720",
-	.dev	= {
-		.platform_data = &msm_camera_sensor_ov2720_data,
-	},
-};
 #endif
 
 static struct msm8960_privacy_light_cfg privacy_light_info = {
@@ -481,15 +458,6 @@
 
 void __init msm8960_init_cam(void)
 {
-	int i;
-	struct platform_device *cam_dev[] = {
-		&msm8960_camera_sensor_imx074,
-#ifdef CONFIG_MT9M114
-		&msm8960_camera_sensor_mt9m114,
-#endif
-		&msm8960_camera_sensor_ov2720,
-	};
-
 	msm_gpiomux_install(msm8960_cam_common_configs,
 			ARRAY_SIZE(msm8960_cam_common_configs));
 
@@ -509,21 +477,14 @@
 
 	if (machine_is_msm8960_liquid()) {
 		struct msm_camera_sensor_info *s_info;
-		s_info = msm8960_camera_sensor_imx074.dev.platform_data;
+		s_info = &msm_camera_sensor_imx074_data;
 		s_info->sensor_platform_info->mount_angle = 180;
-		s_info = msm8960_camera_sensor_ov2720.dev.platform_data;
+		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;
 	}
 
-	for (i = 0; i < ARRAY_SIZE(cam_dev); i++) {
-		struct msm_camera_sensor_info *s_info;
-		s_info = cam_dev[i]->dev.platform_data;
-		msm_get_cam_resources(s_info);
-		platform_device_register(cam_dev[i]);
-	}
-
 	platform_device_register(&msm8960_device_csiphy0);
 	platform_device_register(&msm8960_device_csiphy1);
 	platform_device_register(&msm8960_device_csid0);
@@ -532,4 +493,35 @@
 	platform_device_register(&msm8960_device_vfe);
 	platform_device_register(&msm8960_device_vpe);
 }
+
+#ifdef CONFIG_I2C
+static struct i2c_board_info msm8960_camera_i2c_boardinfo[] = {
+#ifdef CONFIG_IMX074
+	{
+	I2C_BOARD_INFO("imx074", 0x1A),
+	.platform_data = &msm_camera_sensor_imx074_data,
+	},
+#endif
+#ifdef CONFIG_OV2720
+	{
+	I2C_BOARD_INFO("ov2720", 0x6C),
+	.platform_data = &msm_camera_sensor_ov2720_data,
+	},
+#endif
+	{
+	I2C_BOARD_INFO("mt9m114", 0x48),
+	.platform_data = &msm_camera_sensor_mt9m114_data,
+	},
+#ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
+	{
+	I2C_BOARD_INFO("sc628a", 0x6E),
+	},
+#endif
+};
+
+struct msm_camera_board_info msm8960_camera_board_info = {
+	.board_info = msm8960_camera_i2c_boardinfo,
+	.num_i2c_board_info = ARRAY_SIZE(msm8960_camera_i2c_boardinfo),
+};
+#endif
 #endif
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index 936bb1c..58332ec 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -30,9 +30,9 @@
 VREG_CONSUMERS(L2) = {
 	REGULATOR_SUPPLY("8921_l2",		NULL),
 	REGULATOR_SUPPLY("dsi_vdda",		"mipi_dsi.1"),
-	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_camera_imx074.0"),
-	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_camera_ov2720.0"),
-	REGULATOR_SUPPLY("mipi_csi_vdd",	"msm_camera_mt9m114.0"),
+	REGULATOR_SUPPLY("mipi_csi_vdd",	"4-001a"),
+	REGULATOR_SUPPLY("mipi_csi_vdd",	"4-006c"),
+	REGULATOR_SUPPLY("mipi_csi_vdd",	"4-0048"),
 };
 VREG_CONSUMERS(L3) = {
 	REGULATOR_SUPPLY("8921_l3",		NULL),
@@ -71,15 +71,15 @@
 };
 VREG_CONSUMERS(L11) = {
 	REGULATOR_SUPPLY("8921_l11",		NULL),
-	REGULATOR_SUPPLY("cam_vana",		"msm_camera_imx074.0"),
-	REGULATOR_SUPPLY("cam_vana",		"msm_camera_ov2720.0"),
-	REGULATOR_SUPPLY("cam_vana",		"msm_camera_mt9m114.0"),
+	REGULATOR_SUPPLY("cam_vana",		"4-001a"),
+	REGULATOR_SUPPLY("cam_vana",		"4-006c"),
+	REGULATOR_SUPPLY("cam_vana",		"4-0048"),
 };
 VREG_CONSUMERS(L12) = {
 	REGULATOR_SUPPLY("8921_l12",		NULL),
-	REGULATOR_SUPPLY("cam_vdig",		"msm_camera_imx074.0"),
-	REGULATOR_SUPPLY("cam_vdig",		"msm_camera_ov2720.0"),
-	REGULATOR_SUPPLY("cam_vdig",		"msm_camera_mt9m114.0"),
+	REGULATOR_SUPPLY("cam_vdig",		"4-001a"),
+	REGULATOR_SUPPLY("cam_vdig",		"4-006c"),
+	REGULATOR_SUPPLY("cam_vdig",		"4-0048"),
 };
 VREG_CONSUMERS(L14) = {
 	REGULATOR_SUPPLY("8921_l14",		NULL),
@@ -90,9 +90,9 @@
 };
 VREG_CONSUMERS(L16) = {
 	REGULATOR_SUPPLY("8921_l16",		NULL),
-	REGULATOR_SUPPLY("cam_vaf",		"msm_camera_imx074.0"),
-	REGULATOR_SUPPLY("cam_vaf",		"msm_camera_ov2720.0"),
-	REGULATOR_SUPPLY("cam_vaf",		"msm_camera_mt9m114.0"),
+	REGULATOR_SUPPLY("cam_vaf",		"4-001a"),
+	REGULATOR_SUPPLY("cam_vaf",		"4-006c"),
+	REGULATOR_SUPPLY("cam_vaf",		"4-0048"),
 };
 VREG_CONSUMERS(L17) = {
 	REGULATOR_SUPPLY("8921_l17",		NULL),
@@ -201,9 +201,9 @@
 };
 VREG_CONSUMERS(LVS5) = {
 	REGULATOR_SUPPLY("8921_lvs5",		NULL),
-	REGULATOR_SUPPLY("cam_vio",		"msm_camera_imx074.0"),
-	REGULATOR_SUPPLY("cam_vio",		"msm_camera_ov2720.0"),
-	REGULATOR_SUPPLY("cam_vio",		"msm_camera_mt9m114.0"),
+	REGULATOR_SUPPLY("cam_vio",		"4-001a"),
+	REGULATOR_SUPPLY("cam_vio",		"4-006c"),
+	REGULATOR_SUPPLY("cam_vio",		"4-0048"),
 };
 VREG_CONSUMERS(LVS6) = {
 	REGULATOR_SUPPLY("8921_lvs6",		NULL),
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 1b33453..dbda923 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -1974,31 +1974,6 @@
 	int                    len;
 };
 
-#ifdef CONFIG_MSM_CAMERA
-static struct i2c_board_info msm_camera_boardinfo[] __initdata = {
-#ifdef CONFIG_IMX074
-	{
-	I2C_BOARD_INFO("imx074", 0x1A),
-	},
-#endif
-#ifdef CONFIG_OV2720
-	{
-	I2C_BOARD_INFO("ov2720", 0x6C),
-	},
-#endif
-#ifdef CONFIG_MT9M114
-	{
-	I2C_BOARD_INFO("mt9m114", 0x48),
-	},
-#endif
-#ifdef CONFIG_MSM_CAMERA_FLASH_SC628A
-	{
-	I2C_BOARD_INFO("sc628a", 0x6E),
-	},
-#endif
-};
-#endif
-
 /* Sensors DSPS platform data */
 #ifdef CONFIG_MSM_DSPS
 #define DSPS_PIL_GENERIC_NAME		"dsps"
@@ -2085,14 +2060,6 @@
 };
 
 static struct i2c_registry msm8960_i2c_devices[] __initdata = {
-#ifdef CONFIG_MSM_CAMERA
-	{
-		I2C_SURF | I2C_FFA | I2C_FLUID | I2C_LIQUID | I2C_RUMI,
-		MSM_8960_GSBI4_QUP_I2C_BUS_ID,
-		msm_camera_boardinfo,
-		ARRAY_SIZE(msm_camera_boardinfo),
-	},
-#endif
 #ifdef CONFIG_ISL9519_CHARGER
 	{
 		I2C_LIQUID,
@@ -2139,6 +2106,14 @@
 #ifdef CONFIG_I2C
 	u8 mach_mask = 0;
 	int i;
+#ifdef CONFIG_MSM_CAMERA
+	struct i2c_registry msm8960_camera_i2c_devices = {
+		I2C_SURF | I2C_FFA | I2C_FLUID | I2C_LIQUID | I2C_RUMI,
+		MSM_8960_GSBI4_QUP_I2C_BUS_ID,
+		msm8960_camera_board_info.board_info,
+		msm8960_camera_board_info.num_i2c_board_info,
+	};
+#endif
 
 	/* Build the matching 'supported_machs' bitmask */
 	if (machine_is_msm8960_cdp())
@@ -2163,6 +2138,12 @@
 						msm8960_i2c_devices[i].info,
 						msm8960_i2c_devices[i].len);
 	}
+#ifdef CONFIG_MSM_CAMERA
+	if (msm8960_camera_i2c_devices.machs & mach_mask)
+		i2c_register_board_info(msm8960_camera_i2c_devices.bus,
+			msm8960_camera_i2c_devices.info,
+			msm8960_camera_i2c_devices.len);
+#endif
 #endif
 }
 
diff --git a/arch/arm/mach-msm/board-8960.h b/arch/arm/mach-msm/board-8960.h
index 125ae4d..7d35e4d 100644
--- a/arch/arm/mach-msm/board-8960.h
+++ b/arch/arm/mach-msm/board-8960.h
@@ -15,6 +15,7 @@
 
 #include <linux/regulator/gpio-regulator.h>
 #include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/i2c.h>
 #include <linux/i2c/sx150x.h>
 #include <mach/irqs.h>
 #include <mach/rpm-regulator.h>
@@ -71,6 +72,7 @@
 #endif
 
 extern struct sx150x_platform_data msm8960_sx150x_data[];
+extern struct msm_camera_board_info msm8960_camera_board_info;
 void msm8960_init_cam(void);
 void msm8960_init_fb(void);
 void msm8960_init_pmic(void);
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 5521c64..101658c 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5496,11 +5496,9 @@
 	CLK_LOOKUP("core_clk",		pmic_ssbi2_clk.c,	NULL),
 	CLK_LOOKUP("mem_clk",		rpm_msg_ram_p_clk.c,	NULL),
 	CLK_LOOKUP("core_clk",		amp_clk.c,		NULL),
-	CLK_LOOKUP("cam_clk",		cam0_clk.c,		NULL),
-	CLK_LOOKUP("cam_clk",		cam1_clk.c,		NULL),
-	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"msm_camera_imx074.0"),
-	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"msm_camera_mt9m114.0"),
-	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"msm_camera_ov2720.0"),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-001a"),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-006c"),
+	CLK_LOOKUP("cam_clk",		cam0_clk.c,	"4-0048"),
 	CLK_LOOKUP("csi_src_clk",	csi0_src_clk.c,		"msm_csid.0"),
 	CLK_LOOKUP("csi_src_clk",	csi1_src_clk.c,		"msm_csid.1"),
 	CLK_LOOKUP("csi_clk",		csi0_clk.c,		"msm_csid.0"),
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index 0cd1c5c..ae68036 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -219,6 +219,11 @@
 	struct msm_actuator_info *actuator_info;
 };
 
+struct msm_camera_board_info {
+	struct i2c_board_info *board_info;
+	uint8_t num_i2c_board_info;
+};
+
 int msm_get_cam_resources(struct msm_camera_sensor_info *);
 
 struct clk_lookup;
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index ae1f753..1dc6758 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -667,6 +667,8 @@
 void msm_io_dump(void __iomem *addr, int size);
 void msm_io_memcpy(void __iomem *dest_addr, void __iomem *src_addr, u32 len);
 void msm_camio_set_perf_lvl(enum msm_bus_perf_setting);
+void msm_camio_bus_scale_cfg(
+	struct msm_bus_scale_pdata *, enum msm_bus_perf_setting);
 
 void *msm_isp_sync_alloc(int size, gfp_t gfp);
 
@@ -674,4 +676,7 @@
 
 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 *);
 #endif
diff --git a/drivers/media/video/msm/Makefile b/drivers/media/video/msm/Makefile
index 6f39576..5454763 100644
--- a/drivers/media/video/msm/Makefile
+++ b/drivers/media/video/msm/Makefile
@@ -5,6 +5,8 @@
 
 ifeq ($(CONFIG_MSM_CAMERA_V4L2),y)
   EXTRA_CFLAGS += -Idrivers/media/video/msm/csi
+  EXTRA_CFLAGS += -Idrivers/media/video/msm/io
+  EXTRA_CFLAGS += -Idrivers/media/video/msm/sensors
   obj-$(CONFIG_MSM_CAMERA) += msm_isp.o msm.o msm_mem.o msm_mctl.o msm_mctl_buf.o msm_mctl_pp.o
   obj-$(CONFIG_MSM_CAMERA) += io/ sensors/ actuators/ csi/
 else
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 579c4d5..8df6243 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -19,7 +19,7 @@
 #include <linux/spinlock.h>
 #include <linux/proc_fs.h>
 #include "msm.h"
-
+#include "msm_sensor.h"
 
 #define MSM_MAX_CAMERA_SENSORS 5
 
@@ -2294,10 +2294,11 @@
 {
 	int rc = -ENOMEM;
 	struct video_device *pvdev = NULL;
+	struct i2c_client *client = v4l2_get_subdevdata(pcam->mctl.sensor_sdev);
 	D("%s\n", __func__);
 
 	/* first register the v4l2 device */
-	pcam->v4l2_dev.dev = &pcam->pdev->dev;
+	pcam->v4l2_dev.dev = &client->dev;
 	rc = v4l2_device_register(pcam->v4l2_dev.dev, &pcam->v4l2_dev);
 	if (rc < 0)
 		return -EINVAL;
@@ -2314,11 +2315,11 @@
 
 	/* init video device's driver interface */
 	D("sensor name = %s, sizeof(pvdev->name)=%d\n",
-		pcam->pdev->name, sizeof(pvdev->name));
+		pcam->mctl.sensor_sdev->name, sizeof(pvdev->name));
 
 	/* device info - strlcpy is safer than strncpy but
 	   only if architecture supports*/
-	strlcpy(pvdev->name, pcam->pdev->name, sizeof(pvdev->name));
+	strlcpy(pvdev->name, pcam->mctl.sensor_sdev->name, sizeof(pvdev->name));
 
 	pvdev->release   = video_device_release;
 	pvdev->fops	  = &g_msm_fops;
@@ -2418,36 +2419,25 @@
 	struct platform_device *pdev)
 {
 	int rc = 0;
-
-	sync->sdata = pdev->dev.platform_data;
-
 	wake_lock_init(&sync->wake_lock, WAKE_LOCK_IDLE, "msm_camera");
-
-	sync->pdev = pdev;
 	sync->opencnt = 0;
-
 	mutex_init(&sync->lock);
-	D("%s: initialized %s\n", __func__, sync->sdata->sensor_name);
 	return rc;
 }
 
 /* register a msm sensor into the msm device, which will probe the
  * sensor HW. if the HW exist then create a video device (/dev/videoX/)
  * to represent this sensor */
-int msm_sensor_register(struct platform_device *pdev,
-		int (*sensor_probe)(const struct msm_camera_sensor_info *,
-			struct v4l2_subdev *, struct msm_sensor_ctrl *))
+int msm_sensor_register(struct v4l2_subdev *sensor_sd)
 {
-
 	int rc = -EINVAL;
-	struct msm_camera_sensor_info *sdata = pdev->dev.platform_data;
+	struct msm_camera_sensor_info *sdata;
 	struct msm_cam_v4l2_device *pcam;
-	struct v4l2_subdev *sdev = NULL;
-	struct msm_sensor_ctrl *sctrl = NULL;
+	struct msm_sensor_ctrl_t *s_ctrl;
 	struct v4l2_subdev *act_sdev = NULL;
 	struct msm_actuator_ctrl *actctrl = NULL;
 
-	D("%s for %s\n", __func__, pdev->name);
+	D("%s for %s\n", __func__, sensor_sd->name);
 
 	/* allocate the memory for the camera device first */
 	pcam = kzalloc(sizeof(*pcam), GFP_KERNEL);
@@ -2457,44 +2447,15 @@
 		return -ENOMEM;
 	}
 
-	pcam->mctl.sensor_sdev = kzalloc(sizeof(struct v4l2_subdev),
-					 GFP_KERNEL);
-	if (!pcam->mctl.sensor_sdev) {
-		pr_err("%s: could not allocate mem for sensor v4l2_subdev\n",
-			__func__);
-		kfree(pcam);
-		return -ENOMEM;
-	}
-
-	sdev = pcam->mctl.sensor_sdev;
-	snprintf(sdev->name, sizeof(sdev->name), "%s", pdev->name);
-	sctrl = &pcam->mctl.sync.sctrl;
-
-	/* come sensor probe logic */
-	rc = msm_camio_probe_on(pdev);
-	if (rc < 0) {
-		kzfree(pcam);
-		return rc;
-	}
-
-	rc = sensor_probe(sdata, sdev, sctrl);
-	if (rc < 0) {
-		pr_err("%s: failed to detect %s\n",
-			__func__,
-			sdata->sensor_name);
-		msm_camio_probe_off(pdev);
-		kzfree(sdev);
-		kzfree(pcam);
-		return rc;
-	}
+	pcam->mctl.sensor_sdev = sensor_sd;
+	s_ctrl = get_sctrl(sensor_sd);
+	sdata = (struct msm_camera_sensor_info *) s_ctrl->sensordata;
 
 	pcam->mctl.act_sdev = kzalloc(sizeof(struct v4l2_subdev),
-					 GFP_KERNEL);
+								  GFP_KERNEL);
 	if (!pcam->mctl.act_sdev) {
 		pr_err("%s: could not allocate mem for actuator v4l2_subdev\n",
-			__func__);
-		msm_camio_probe_off(pdev);
-		kzfree(sdev);
+			   __func__);
 		kfree(pcam);
 		return -ENOMEM;
 	}
@@ -2503,20 +2464,17 @@
 	actctrl = &pcam->mctl.sync.actctrl;
 
 	msm_actuator_probe(sdata->actuator_info,
-			act_sdev, actctrl);
-
-	msm_camio_probe_off(pdev);
+					   act_sdev, actctrl);
 
 	/* setup a manager object*/
-	rc = msm_sync_init(&pcam->mctl.sync, pdev);
+	rc = msm_sync_init(&pcam->mctl.sync, NULL);
 	if (rc < 0)
 		goto failure;
 	D("%s: pcam =0x%p\n", __func__, pcam);
 	D("%s: &pcam->mctl.sync =0x%p\n", __func__, &pcam->mctl.sync);
 
+	pcam->mctl.sync.sdata = sdata;
 	pcam->mctl.sync.pcam_sync = pcam;
-	/* bind the driver device to the sensor device */
-	pcam->pdev = pdev;
 
 	/* init the user count and lock*/
 	pcam->use_count = 0;
@@ -2527,7 +2485,6 @@
 	if (rc < 0)
 		goto failure;
 
-	/* now initialize the camera device object */
 	rc  = msm_cam_dev_init(pcam);
 	if (rc < 0)
 		goto failure;
@@ -2541,39 +2498,35 @@
 
 	g_server_dev.camera_info.s_mount_angle
 	[g_server_dev.camera_info.num_cameras]
-	= sctrl->s_mount_angle;
+	= sdata->sensor_platform_info->mount_angle;
 
 	g_server_dev.camera_info.is_internal_cam
 	[g_server_dev.camera_info.num_cameras]
-	= sctrl->s_camera_type;
+	= sdata->camera_type;
 
 	g_server_dev.camera_info.num_cameras++;
 
 	D("%s done, rc = %d\n", __func__, rc);
 	D("%s number of sensors connected is %d\n", __func__,
 			g_server_dev.camera_info.num_cameras);
-/*
-	if (g_server_dev.camera_info.num_cameras == 1) {
-		rc = add_axi_qos();
-		if (rc < 0)
-			goto failure;
-	}
-*/
+
 	/* register the subdevice, must be done for callbacks */
-	rc = v4l2_device_register_subdev(&pcam->v4l2_dev, sdev);
+	rc = v4l2_device_register_subdev(&pcam->v4l2_dev, sensor_sd);
 	if (rc < 0) {
 		D("%s sensor sub device register failed\n",
 			__func__);
 		goto failure;
 	}
+
 	if (sdata->actuator_info) {
 		rc = v4l2_device_register_subdev(&pcam->v4l2_dev, act_sdev);
 		if (rc < 0) {
 			D("%s actuator sub device register failed\n",
-				__func__);
+			  __func__);
 			goto failure;
 		}
 	}
+
 	pcam->vnode_id = vnode_count++;
 	return rc;
 
@@ -2581,9 +2534,7 @@
 	/* mutex_destroy not needed at this moment as the associated
 	implemenation of mutex_init is not consuming resources */
 	msm_sync_destroy(&pcam->mctl.sync);
-	pcam->pdev = NULL;
 	kfree(act_sdev);
-	kfree(sdev);
 	kzfree(pcam);
 	return rc;
 }
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 3e3b9c8..5fc3e6a 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -396,9 +396,7 @@
 */
 int msm_isp_register(struct msm_cam_server_dev *psvr);
 void msm_isp_unregister(struct msm_cam_server_dev *psvr);
-int msm_sensor_register(struct platform_device *pdev,
-	int (*sensor_probe)(const struct msm_camera_sensor_info *,
-	struct v4l2_subdev *, struct msm_sensor_ctrl *));
+int msm_sensor_register(struct v4l2_subdev *);
 int msm_isp_init_module(int g_num_config_nodes);
 
 int msm_mctl_init_module(struct msm_cam_v4l2_device *pcam);
diff --git a/drivers/media/video/msm/msm_io_8960.c b/drivers/media/video/msm/msm_io_8960.c
index ec18a93..3168bb6 100644
--- a/drivers/media/video/msm/msm_io_8960.c
+++ b/drivers/media/video/msm/msm_io_8960.c
@@ -136,10 +136,10 @@
 	msm_io_dump(dest_addr, len);
 }
 
-static int msm_camera_vreg_enable(struct platform_device *pdev)
+static int msm_camera_vreg_enable(struct device *dev)
 {
 	if (mipi_csi_vdd == NULL) {
-		mipi_csi_vdd = regulator_get(&pdev->dev, "mipi_csi_vdd");
+		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;
@@ -164,7 +164,7 @@
 		}
 	}
 	if (cam_vana == NULL) {
-		cam_vana = regulator_get(&pdev->dev, "cam_vana");
+		cam_vana = regulator_get(dev, "cam_vana");
 		if (IS_ERR(cam_vana)) {
 			CDBG("%s: VREG CAM VANA get failed\n", __func__);
 			cam_vana = NULL;
@@ -188,7 +188,7 @@
 		}
 	}
 	if (cam_vio == NULL) {
-		cam_vio = regulator_get(&pdev->dev, "cam_vio");
+		cam_vio = regulator_get(dev, "cam_vio");
 		if (IS_ERR(cam_vio)) {
 			CDBG("%s: VREG VIO get failed\n", __func__);
 			cam_vio = NULL;
@@ -200,7 +200,7 @@
 		}
 	}
 	if (cam_vdig == NULL) {
-		cam_vdig = regulator_get(&pdev->dev, "cam_vdig");
+		cam_vdig = regulator_get(dev, "cam_vdig");
 		if (IS_ERR(cam_vdig)) {
 			CDBG("%s: VREG CAM VDIG get failed\n", __func__);
 			cam_vdig = NULL;
@@ -224,7 +224,7 @@
 		}
 	}
 	if (cam_vaf == NULL) {
-		cam_vaf = regulator_get(&pdev->dev, "cam_vaf");
+		cam_vaf = regulator_get(dev, "cam_vaf");
 		if (IS_ERR(cam_vaf)) {
 			CDBG("%s: VREG CAM VAF get failed\n", __func__);
 			cam_vaf = NULL;
@@ -456,9 +456,8 @@
 	return rc;
 }
 
-static int config_gpio_table(int gpio_en)
+static int config_gpio_table(struct msm_camera_sensor_info *sinfo, int gpio_en)
 {
-	struct msm_camera_sensor_info *sinfo = camio_dev->dev.platform_data;
 	struct msm_camera_gpio_conf *gpio_conf = sinfo->gpio_conf;
 	int rc = 0, i = 0;
 
@@ -567,73 +566,47 @@
 	.control	= PM8XXX_MPP_CS_CTRL_DISABLE,
 };
 
-int msm_camio_sensor_clk_on(struct platform_device *pdev)
+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 = pdev->dev.platform_data;
+	struct msm_camera_sensor_info *sinfo = dev->platform_data;
 	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camio_dev = pdev;
 	camio_clk = camdev->ioclk;
 
-	msm_camera_vreg_enable(pdev);
+	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);
 	}
-	msleep(20);
-	rc = config_gpio_table(1);
-	if (rc < 0)
-		return rc;
-	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
+	return msm_cam_clk_enable(dev, cam_clk_info,
+		&camio_cam_clk, ARRAY_SIZE(cam_clk_info), 1);
 }
 
-int msm_camio_sensor_clk_off(struct platform_device *pdev)
+int msm_sensor_probe_off(struct device *dev)
 {
 	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	msm_camera_vreg_disable();
+	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);
 	}
-	rc = config_gpio_table(0);
-	if (rc < 0)
-		return rc;
-	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
-}
-
-void msm_camio_vfe_blk_reset(void)
-{
-	return;
-}
-
-int msm_camio_probe_on(struct platform_device *pdev)
-{
-	int rc = 0;
-	struct msm_camera_sensor_info *sinfo = pdev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-	camio_dev = pdev;
-	camio_clk = camdev->ioclk;
-
-	rc = config_gpio_table(1);
-	if (rc < 0)
-		return rc;
-	msm_camera_vreg_enable(pdev);
-	return msm_camio_clk_enable(CAMIO_CAM_MCLK_CLK);
-}
-
-int msm_camio_probe_off(struct platform_device *pdev)
-{
-	int rc = 0;
 	msm_camera_vreg_disable();
-	rc = config_gpio_table(0);
+	rc = config_gpio_table(sinfo, 0);
 	if (rc < 0)
 		return rc;
-	return msm_camio_clk_disable(CAMIO_CAM_MCLK_CLK);
+	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)
@@ -653,16 +626,13 @@
 	}
 }
 
-void msm_camio_set_perf_lvl(enum msm_bus_perf_setting perf_setting)
+void msm_camio_bus_scale_cfg(struct msm_bus_scale_pdata *cam_bus_scale_table,
+		enum msm_bus_perf_setting perf_setting)
 {
 	static uint32_t bus_perf_client;
-	struct msm_camera_sensor_info *sinfo = camio_dev->dev.platform_data;
-	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
-
 	int rc = 0;
 	switch (perf_setting) {
 	case S_INIT:
-		cam_bus_scale_table = camdev->cam_bus_scale_table;
 		bus_perf_client =
 			msm_bus_scale_register_client(cam_bus_scale_table);
 		if (!bus_perf_client) {
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 2adbbd2..759ac47 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -31,6 +31,7 @@
 #include "msm_csid.h"
 #include "msm_csiphy.h"
 #include "msm_ispif.h"
+#include "msm_sensor.h"
 
 #ifdef CONFIG_MSM_CAMERA_DEBUG
 #define D(fmt, args...) pr_debug("msm_mctl: " fmt, ##args)
@@ -151,7 +152,7 @@
 		return -EFAULT;
 	}
 
-	sdata = sync->pdev->dev.platform_data;
+	sdata = sync->sdata;
 	D("%s: sensor_name %s\n", __func__, sdata->sensor_name);
 
 	memcpy(&info.name[0], sdata->sensor_name, MAX_SENSOR_NAME);
@@ -175,8 +176,9 @@
 	unsigned int notification, void *arg)
 {
 	int rc = -EINVAL;
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(p_mctl->sensor_sdev);
 	struct msm_camera_sensor_info *sinfo =
-			p_mctl->plat_dev->dev.platform_data;
+		(struct msm_camera_sensor_info *) s_ctrl->sensordata;
 	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
 	uint8_t csid_core = camdev->csid_core;
 	switch (notification) {
@@ -258,7 +260,8 @@
 			break;
 
 	case MSM_CAM_IOCTL_SENSOR_IO_CFG:
-			rc = p_mctl->sync.sctrl.s_config(argp);
+		rc = v4l2_subdev_call(p_mctl->sensor_sdev,
+			core, ioctl, VIDIOC_MSM_SENSOR_CFG, argp);
 			break;
 
 	case MSM_CAM_IOCTL_SENSOR_V4l2_S_CTRL: {
@@ -475,8 +478,10 @@
 {
 	int rc = 0;
 	struct msm_sync *sync = NULL;
-	struct msm_camera_sensor_info *sinfo;
-	struct msm_camera_device_platform_data *camdev;
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(p_mctl->sensor_sdev);
+	struct msm_camera_sensor_info *sinfo =
+		(struct msm_camera_sensor_info *) s_ctrl->sensordata;
+	struct msm_camera_device_platform_data *camdev = sinfo->pdata;
 	uint8_t csid_core;
 	D("%s\n", __func__);
 	if (!p_mctl) {
@@ -493,10 +498,6 @@
 		uint32_t csid_version;
 		wake_lock(&sync->wake_lock);
 
-		sinfo = sync->pdev->dev.platform_data;
-		sync->pdev->resource = sinfo->resource;
-		sync->pdev->num_resources = sinfo->num_resources;
-		camdev = sinfo->pdata;
 		csid_core = camdev->csid_core;
 		rc = msm_mctl_register_subdevs(p_mctl, csid_core);
 		if (rc < 0) {
@@ -505,14 +506,6 @@
 			goto msm_open_done;
 		}
 
-		/* turn on clock */
-		rc = msm_camio_sensor_clk_on(sync->pdev);
-		if (rc < 0) {
-			pr_err("%s: msm_camio_sensor_clk_on failed:%d\n",
-			 __func__, rc);
-			goto msm_open_done;
-		}
-
 		rc = v4l2_subdev_call(p_mctl->csiphy_sdev, core, ioctl,
 			VIDIOC_MSM_CSIPHY_INIT, NULL);
 		if (rc < 0) {
@@ -548,8 +541,7 @@
 		}
 
 		/* then sensor - move sub dev later*/
-		if (sync->sctrl.s_init)
-			rc = sync->sctrl.s_init(sync->sdata);
+		rc = v4l2_subdev_call(p_mctl->sensor_sdev, core, s_power, 1);
 
 		if (rc < 0) {
 			pr_err("%s: isp init failed: %d\n", __func__, rc);
@@ -583,8 +575,6 @@
 static int msm_mctl_release(struct msm_cam_media_controller *p_mctl)
 {
 	int rc = 0;
-	struct msm_sync *sync = &(p_mctl->sync);
-
 	v4l2_subdev_call(p_mctl->ispif_sdev, core, ioctl,
 		VIDIOC_MSM_ISPIF_RELEASE, NULL);
 
@@ -598,21 +588,16 @@
 		VIDIOC_MSM_CSIPHY_RELEASE, NULL);
 
 	if (p_mctl->sync.actctrl.a_power_down)
-		p_mctl->sync.actctrl.a_power_down(sync->sdata->actuator_info);
+		p_mctl->sync.actctrl.a_power_down(
+			p_mctl->sync.sdata->actuator_info);
 
-	if (p_mctl->sync.sctrl.s_release)
-		p_mctl->sync.sctrl.s_release();
-
-	rc = msm_camio_sensor_clk_off(sync->pdev);
-	if (rc < 0)
-		pr_err("%s: msm_camio_sensor_clk_off failed:%d\n",
-			 __func__, rc);
+	v4l2_subdev_call(p_mctl->sensor_sdev, core, s_power, 0);
 
 	pm_qos_update_request(&p_mctl->pm_qos_req_list,
 				PM_QOS_DEFAULT_VALUE);
 	pm_qos_remove_request(&p_mctl->pm_qos_req_list);
 
-	wake_unlock(&sync->wake_lock);
+	wake_unlock(&p_mctl->sync.wake_lock);
 	return rc;
 }
 
@@ -693,7 +678,6 @@
 	pmctl->mctl_cmd = msm_mctl_cmd;
 	pmctl->mctl_notify = msm_mctl_notify;
 	pmctl->mctl_release = msm_mctl_release;
-	pmctl->plat_dev = pcam->pdev;
 	/* init mctl buf */
 	msm_mctl_buf_init(pcam);
 	memset(&pmctl->pp_info, 0, sizeof(pmctl->pp_info));
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index dcece44..b04f07c 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -731,7 +731,9 @@
 
 static int vfe32_start_recording(void)
 {
-	msm_camio_set_perf_lvl(S_VIDEO);
+	struct msm_sync *sync = vfe_syncdata;
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_VIDEO);
 	vfe32_ctrl->recording_state = VFE_REC_STATE_START_REQUESTED;
 	msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
 	return 0;
@@ -739,9 +741,11 @@
 
 static int vfe32_stop_recording(void)
 {
+	struct msm_sync *sync = vfe_syncdata;
 	vfe32_ctrl->recording_state = VFE_REC_STATE_STOP_REQUESTED;
 	msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD);
-	msm_camio_set_perf_lvl(S_PREVIEW);
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
 	return 0;
 }
 
@@ -753,6 +757,7 @@
 
 static int vfe32_zsl(void)
 {
+	struct msm_sync *sync = vfe_syncdata;
 	uint32_t irq_comp_mask = 0;
 	/* capture command is valid for both idle and active state. */
 	irq_comp_mask	=
@@ -811,7 +816,8 @@
 	}
 	msm_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 	vfe32_start_common();
-	msm_camio_set_perf_lvl(S_ZSL);
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_ZSL);
 
 	msm_io_w(1, vfe32_ctrl->vfebase + 0x18C);
 	msm_io_w(1, vfe32_ctrl->vfebase + 0x188);
@@ -869,7 +875,8 @@
 	}
 	msm_io_w(irq_comp_mask, vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 	msm_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
-	msm_camio_set_perf_lvl(S_CAPTURE);
+	msm_camio_bus_scale_cfg(
+		p_sync->sdata->pdata->cam_bus_scale_table, S_CAPTURE);
 	vfe32_start_common();
 	msm_io_r(vfe32_ctrl->vfebase + VFE_IRQ_COMP_MASK);
 	/* for debug */
@@ -881,6 +888,7 @@
 static int vfe32_start(void)
 {
 	uint32_t irq_comp_mask = 0;
+	struct msm_sync *sync = vfe_syncdata;
 	/* start command now is only good for continuous mode. */
 	if ((vfe32_ctrl->operation_mode != VFE_MODE_OF_OPERATION_CONTINUOUS) &&
 		(vfe32_ctrl->operation_mode != VFE_MODE_OF_OPERATION_VIDEO))
@@ -920,7 +928,8 @@
 		msm_io_w(1, vfe32_ctrl->vfebase +
 			vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out0.ch2]);
 	}
-	msm_camio_set_perf_lvl(S_PREVIEW);
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
 	vfe32_start_common();
 	return 0;
 }
@@ -3683,6 +3692,7 @@
 	struct platform_device *pdev)
 {
 	int rc = 0;
+	struct msm_sync *sync = data;
 	v4l2_set_subdev_hostdata(sd, data);
 	vfe_syncdata = data;
 
@@ -3735,8 +3745,10 @@
 	if (rc < 0)
 		goto vfe_clk_enable_failed;
 
-	msm_camio_set_perf_lvl(S_INIT);
-	msm_camio_set_perf_lvl(S_PREVIEW);
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_INIT);
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_PREVIEW);
 
 	if (msm_io_r(vfe32_ctrl->vfebase + V32_GET_HW_VERSION_OFF) ==
 		VFE32_HW_NUMBER)
@@ -3759,6 +3771,7 @@
 
 void msm_vfe_subdev_release(struct platform_device *pdev)
 {
+	struct msm_sync *sync = vfe_syncdata;
 	msm_cam_clk_enable(&vfe32_ctrl->pdev->dev, vfe32_clk_info,
 			vfe32_ctrl->vfe_clk, ARRAY_SIZE(vfe32_clk_info), 0);
 	if (vfe32_ctrl->fs_vfe) {
@@ -3774,7 +3787,8 @@
 	if (atomic_read(&irq_cnt))
 		pr_warning("%s, Warning IRQ Count not ZERO\n", __func__);
 
-	msm_camio_set_perf_lvl(S_EXIT);
+	msm_camio_bus_scale_cfg(
+		sync->sdata->pdata->cam_bus_scale_table, S_EXIT);
 	vfe_syncdata = NULL;
 }
 
diff --git a/drivers/media/video/msm/sensors/imx074_v4l2.c b/drivers/media/video/msm/sensors/imx074_v4l2.c
index f721441..c77cfc3 100644
--- a/drivers/media/video/msm/sensors/imx074_v4l2.c
+++ b/drivers/media/video/msm/sensors/imx074_v4l2.c
@@ -211,23 +211,8 @@
 	.vert_offset = 3,
 };
 
-static int imx074_sensor_config(void __user *argp)
-{
-	return msm_sensor_config(&imx074_s_ctrl, argp);
-}
-
 static struct sensor_calib_data imx074_calib_data;
 
-static int imx074_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	return msm_sensor_open_init(&imx074_s_ctrl, data);
-}
-
-static int imx074_sensor_release(void)
-{
-	return msm_sensor_release(&imx074_s_ctrl);
-}
-
 static const struct i2c_device_id imx074_i2c_id[] = {
 	{SENSOR_NAME, (kernel_ulong_t)&imx074_s_ctrl},
 	{ }
@@ -276,31 +261,16 @@
 	.data_tbl_size = ARRAY_SIZE(imx074_eeprom_data_tbl),
 };
 
-static int imx074_sensor_v4l2_probe(const struct msm_camera_sensor_info *info,
-	struct v4l2_subdev *sdev, struct msm_sensor_ctrl *s)
-{
-	return msm_sensor_v4l2_probe(&imx074_s_ctrl, info, sdev, s);
-}
-
-static int imx074_probe(struct platform_device *pdev)
-{
-	return msm_sensor_register(pdev, imx074_sensor_v4l2_probe);
-}
-
-struct platform_driver imx074_driver = {
-	.probe = imx074_probe,
-	.driver = {
-		.name = PLATFORM_DRIVER_NAME,
-		.owner = THIS_MODULE,
-	},
-};
-
 static int __init msm_sensor_init_module(void)
 {
-	return platform_driver_register(&imx074_driver);
+	return i2c_add_driver(&imx074_i2c_driver);
 }
 
-static struct v4l2_subdev_core_ops imx074_subdev_core_ops;
+static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
 static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
 	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
 };
@@ -322,12 +292,9 @@
 	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
 	.sensor_mode_init = msm_sensor_mode_init,
 	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = imx074_sensor_config,
-	.sensor_open_init = imx074_sensor_open_init,
-	.sensor_release = imx074_sensor_release,
+	.sensor_config = msm_sensor_config,
 	.sensor_power_up = msm_sensor_power_up,
 	.sensor_power_down = msm_sensor_power_down,
-	.sensor_probe = msm_sensor_probe,
 };
 
 static struct msm_sensor_reg_t imx074_regs = {
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index e67f9cd..d31de14 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -177,7 +177,7 @@
 {
 	int32_t rc = 0;
 
-	v4l2_subdev_notify(s_ctrl->sensor_v4l2_subdev,
+	v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
 		NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
 		PIX0, ISPIF_OFF_IMMEDIATELY));
 	s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
@@ -190,23 +190,23 @@
 		msm_sensor_write_res_settings(s_ctrl, res);
 		if (s_ctrl->curr_csi_params != s_ctrl->csi_params[res]) {
 			s_ctrl->curr_csi_params = s_ctrl->csi_params[res];
-			v4l2_subdev_notify(s_ctrl->sensor_v4l2_subdev,
+			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
 				NOTIFY_CSID_CFG,
 				&s_ctrl->curr_csi_params->csid_params);
-			v4l2_subdev_notify(s_ctrl->sensor_v4l2_subdev,
+			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
 						NOTIFY_CID_CHANGE, NULL);
 			mb();
-			v4l2_subdev_notify(s_ctrl->sensor_v4l2_subdev,
+			v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
 				NOTIFY_CSIPHY_CFG,
 				&s_ctrl->curr_csi_params->csiphy_params);
 			mb();
 			msleep(20);
 		}
 
-		v4l2_subdev_notify(s_ctrl->sensor_v4l2_subdev,
+		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
 			NOTIFY_PCLK_CHANGE, &s_ctrl->msm_sensor_reg->
 			output_settings[res].op_pixel_clk);
-		v4l2_subdev_notify(s_ctrl->sensor_v4l2_subdev,
+		v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
 			NOTIFY_ISPIF_STREAM, (void *)ISPIF_STREAM(
 			PIX0, ISPIF_ON_FRAME_BOUNDARY));
 		s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
@@ -269,6 +269,19 @@
 	return rc;
 }
 
+long msm_sensor_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg)
+{
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+	void __user *argp = (void __user *)arg;
+	switch (cmd) {
+	case VIDIOC_MSM_SENSOR_CFG:
+		return s_ctrl->func_tbl->sensor_config(s_ctrl, argp);
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
 int32_t msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl, void __user *argp)
 {
 	struct sensor_cfg_data cdata;
@@ -396,10 +409,12 @@
 	return rc;
 }
 
-int32_t msm_sensor_power_up(const struct msm_camera_sensor_info *data)
+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");
@@ -417,9 +432,11 @@
 	return rc;
 }
 
-int32_t msm_sensor_power_down(const struct msm_camera_sensor_info *data)
+int32_t msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
 {
+	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);
@@ -448,64 +465,37 @@
 	return rc;
 }
 
+struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct msm_sensor_ctrl_t, sensor_v4l2_subdev);
+}
+
 int32_t msm_sensor_i2c_probe(struct i2c_client *client,
 	const struct i2c_device_id *id)
 {
 	int rc = 0;
-	struct msm_sensor_ctrl_t *this_ctrl;
+	struct msm_sensor_ctrl_t *s_ctrl;
 	CDBG("%s_i2c_probe called\n", client->name);
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 		CDBG("i2c_check_functionality failed\n");
 		rc = -EFAULT;
-		goto probe_failure;
+		return rc;
 	}
 
-	this_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
-	if (this_ctrl->sensor_i2c_client != NULL) {
-		this_ctrl->sensor_i2c_client->client = client;
-		if (this_ctrl->sensor_i2c_addr != 0)
-			this_ctrl->sensor_i2c_client->client->addr =
-				this_ctrl->sensor_i2c_addr;
+	s_ctrl = (struct msm_sensor_ctrl_t *)(id->driver_data);
+	if (s_ctrl->sensor_i2c_client != NULL) {
+		s_ctrl->sensor_i2c_client->client = client;
+		if (s_ctrl->sensor_i2c_addr != 0)
+			s_ctrl->sensor_i2c_client->client->addr =
+				s_ctrl->sensor_i2c_addr;
 	} else {
 		rc = -EFAULT;
+		return rc;
 	}
 
-probe_failure:
-	CDBG("%s_i2c_probe failed\n", client->name);
-	return rc;
-}
+	s_ctrl->sensordata = client->dev.platform_data;
 
-int32_t msm_sensor_release(struct msm_sensor_ctrl_t *s_ctrl)
-{
-	mutex_lock(s_ctrl->msm_sensor_mutex);
-	s_ctrl->func_tbl->sensor_power_down(s_ctrl->sensordata);
-	mutex_unlock(s_ctrl->msm_sensor_mutex);
-	CDBG("%s completed\n", __func__);
-	return 0;
-}
-
-int32_t msm_sensor_open_init(struct msm_sensor_ctrl_t *s_ctrl,
-				const struct msm_camera_sensor_info *data)
-{
-	if (data)
-		s_ctrl->sensordata = data;
-
-	return s_ctrl->func_tbl->sensor_power_up(data);
-}
-
-int32_t msm_sensor_probe(struct msm_sensor_ctrl_t *s_ctrl,
-		const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s)
-{
-	int rc = 0;
-	rc = i2c_add_driver(s_ctrl->sensor_i2c_driver);
-	if (rc < 0 || s_ctrl->sensor_i2c_client->client == NULL) {
-		rc = -ENOTSUPP;
-		CDBG("I2C add driver failed");
-		goto probe_fail;
-	}
-
-	rc = s_ctrl->func_tbl->sensor_power_up(info);
+	rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
 	if (rc < 0)
 		goto probe_fail;
 
@@ -532,45 +522,38 @@
 		}
 	}
 
-	s->s_init = s_ctrl->func_tbl->sensor_open_init;
-	s->s_release = s_ctrl->func_tbl->sensor_release;
-	s->s_config  = s_ctrl->func_tbl->sensor_config;
-	s->s_camera_type = info->camera_type;
-	if (info->sensor_platform_info != NULL)
-		s->s_mount_angle = info->sensor_platform_info->mount_angle;
-	else
-		s->s_mount_angle = 0;
+	snprintf(s_ctrl->sensor_v4l2_subdev.name,
+		sizeof(s_ctrl->sensor_v4l2_subdev.name), "%s", id->name);
+	v4l2_i2c_subdev_init(&s_ctrl->sensor_v4l2_subdev, client,
+		s_ctrl->sensor_v4l2_subdev_ops);
 
+	msm_sensor_register(&s_ctrl->sensor_v4l2_subdev);
 	goto power_down;
 probe_fail:
-	i2c_del_driver(s_ctrl->sensor_i2c_driver);
+	CDBG("%s_i2c_probe failed\n", client->name);
 power_down:
-	s_ctrl->func_tbl->sensor_power_down(info);
+	s_ctrl->func_tbl->sensor_power_down(s_ctrl);
 	return rc;
 }
 
-int32_t msm_sensor_v4l2_probe(struct msm_sensor_ctrl_t *s_ctrl,
-	const struct msm_camera_sensor_info *info,
-	struct v4l2_subdev *sdev, struct msm_sensor_ctrl *s)
+int32_t msm_sensor_power(struct v4l2_subdev *sd, int on)
 {
-	int32_t rc = 0;
-	rc = s_ctrl->func_tbl->sensor_probe(s_ctrl, info, s);
-	if (rc < 0)
-		return rc;
-
-	s_ctrl->sensor_v4l2_subdev = sdev;
-	v4l2_i2c_subdev_init(s_ctrl->sensor_v4l2_subdev,
-		s_ctrl->sensor_i2c_client->client,
-		s_ctrl->sensor_v4l2_subdev_ops);
-	s_ctrl->sensor_v4l2_subdev->dev_priv = (void *) s_ctrl;
+	int rc = 0;
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+	mutex_lock(s_ctrl->msm_sensor_mutex);
+	if (on)
+		rc = s_ctrl->func_tbl->sensor_power_up(s_ctrl);
+	else
+		rc = s_ctrl->func_tbl->sensor_power_down(s_ctrl);
+	mutex_unlock(s_ctrl->msm_sensor_mutex);
 	return rc;
 }
 
 int32_t msm_sensor_v4l2_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
 			   enum v4l2_mbus_pixelcode *code)
 {
-	struct msm_sensor_ctrl_t *s_ctrl =
-		(struct msm_sensor_ctrl_t *) sd->dev_priv;
+	struct msm_sensor_ctrl_t *s_ctrl = get_sctrl(sd);
+
 	if ((unsigned int)index >= s_ctrl->sensor_v4l2_subdev_info_size)
 		return -EINVAL;
 
diff --git a/drivers/media/video/msm/sensors/msm_sensor.h b/drivers/media/video/msm/sensors/msm_sensor.h
index f1a15b2..e06f628 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.h
+++ b/drivers/media/video/msm/sensors/msm_sensor.h
@@ -10,6 +10,9 @@
  * GNU General Public License for more details.
  */
 
+#ifndef MSM_SENSOR_H
+#define MSM_SENSOR_H
+
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/i2c.h>
@@ -22,7 +25,6 @@
 #include <mach/gpio.h>
 #include <media/msm_camera.h>
 #include <media/v4l2-subdev.h>
-#include "msm.h"
 #include "msm_camera_i2c.h"
 #include "msm_camera_eeprom.h"
 #define Q8  0x00000100
@@ -124,19 +126,14 @@
 		int, struct sensor_init_cfg *);
 	int32_t (*sensor_get_output_info) (struct msm_sensor_ctrl_t *,
 		struct sensor_output_info_t *);
-	int (*sensor_config) (void __user *);
-	int (*sensor_open_init) (const struct msm_camera_sensor_info *);
-	int (*sensor_release) (void);
+	int (*sensor_config) (struct msm_sensor_ctrl_t *, void __user *);
 	int (*sensor_power_down)
-		(const struct msm_camera_sensor_info *);
-	int (*sensor_power_up) (const struct msm_camera_sensor_info *);
-	int (*sensor_probe) (struct msm_sensor_ctrl_t *s_ctrl,
-			const struct msm_camera_sensor_info *info,
-			struct msm_sensor_ctrl *s);
+		(struct msm_sensor_ctrl_t *);
+	int (*sensor_power_up) (struct msm_sensor_ctrl_t *);
 };
 
 struct msm_sensor_ctrl_t {
-	const struct  msm_camera_sensor_info *sensordata;
+	struct  msm_camera_sensor_info *sensordata;
 	struct i2c_client *msm_sensor_client;
 	struct i2c_driver *sensor_i2c_driver;
 	struct msm_camera_i2c_client *sensor_i2c_client;
@@ -162,7 +159,7 @@
 	struct msm_camera_csi2_params *curr_csi_params;
 	struct msm_camera_csi2_params **csi_params;
 
-	struct v4l2_subdev *sensor_v4l2_subdev;
+	struct v4l2_subdev sensor_v4l2_subdev;
 	struct v4l2_subdev_info *sensor_v4l2_subdev_info;
 	uint8_t sensor_v4l2_subdev_info_size;
 	struct v4l2_subdev_ops *sensor_v4l2_subdev_ops;
@@ -188,22 +185,13 @@
 		struct sensor_output_info_t *);
 int32_t msm_sensor_config(struct msm_sensor_ctrl_t *s_ctrl,
 			void __user *argp);
-int32_t msm_sensor_power_up(const struct msm_camera_sensor_info *data);
-int32_t msm_sensor_power_down(const struct msm_camera_sensor_info *data);
+int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl);
+int32_t msm_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl);
 
 int32_t msm_sensor_match_id(struct msm_sensor_ctrl_t *s_ctrl);
 int msm_sensor_i2c_probe(struct i2c_client *client,
 	const struct i2c_device_id *id);
-int32_t msm_sensor_release(struct msm_sensor_ctrl_t *s_ctrl);
-int32_t msm_sensor_open_init(struct msm_sensor_ctrl_t *s_ctrl,
-				const struct msm_camera_sensor_info *data);
-int msm_sensor_probe(struct msm_sensor_ctrl_t *s_ctrl,
-		const struct msm_camera_sensor_info *info,
-		struct msm_sensor_ctrl *s);
-
-int msm_sensor_v4l2_probe(struct msm_sensor_ctrl_t *s_ctrl,
-	const struct msm_camera_sensor_info *info,
-	struct v4l2_subdev *sdev, struct msm_sensor_ctrl *s);
+int32_t msm_sensor_power(struct v4l2_subdev *sd, int on);
 
 int32_t msm_sensor_v4l2_s_ctrl(struct v4l2_subdev *sd,
 	struct v4l2_control *ctrl);
@@ -231,3 +219,13 @@
 			int update_type, int res);
 
 int msm_sensor_enable_debugfs(struct msm_sensor_ctrl_t *s_ctrl);
+
+long msm_sensor_subdev_ioctl(struct v4l2_subdev *sd,
+			unsigned int cmd, void *arg);
+
+struct msm_sensor_ctrl_t *get_sctrl(struct v4l2_subdev *sd);
+
+#define VIDIOC_MSM_SENSOR_CFG \
+	_IOWR('V', BASE_VIDIOC_PRIVATE + 10, void __user *)
+
+#endif
diff --git a/drivers/media/video/msm/sensors/mt9m114_v4l2.c b/drivers/media/video/msm/sensors/mt9m114_v4l2.c
index fc45705..a1e56f7 100644
--- a/drivers/media/video/msm/sensors/mt9m114_v4l2.c
+++ b/drivers/media/video/msm/sensors/mt9m114_v4l2.c
@@ -1221,21 +1221,6 @@
 	.sensor_id = 0x2481,
 };
 
-static int mt9m114_sensor_config(void __user *argp)
-{
-	return msm_sensor_config(&mt9m114_s_ctrl, argp);
-}
-
-static int mt9m114_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	return msm_sensor_open_init(&mt9m114_s_ctrl, data);
-}
-
-static int mt9m114_sensor_release(void)
-{
-	return msm_sensor_release(&mt9m114_s_ctrl);
-}
-
 static const struct i2c_device_id mt9m114_i2c_id[] = {
 	{SENSOR_NAME, (kernel_ulong_t)&mt9m114_s_ctrl},
 	{ }
@@ -1253,33 +1238,16 @@
 	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
 };
 
-static int mt9m114_sensor_v4l2_probe(const struct msm_camera_sensor_info *info,
-	struct v4l2_subdev *sdev, struct msm_sensor_ctrl *s)
-{
-	return msm_sensor_v4l2_probe(&mt9m114_s_ctrl, info, sdev, s);
-}
-
-static int mt9m114_probe(struct platform_device *pdev)
-{
-	return msm_sensor_register(pdev, mt9m114_sensor_v4l2_probe);
-}
-
-struct platform_driver mt9m114_driver = {
-	.probe = mt9m114_probe,
-	.driver = {
-		.name = PLATFORM_DRIVER_NAME,
-		.owner = THIS_MODULE,
-	},
-};
-
 static int __init msm_sensor_init_module(void)
 {
-	return platform_driver_register(&mt9m114_driver);
+	return i2c_add_driver(&mt9m114_i2c_driver);
 }
 
 static struct v4l2_subdev_core_ops mt9m114_subdev_core_ops = {
 	.s_ctrl = msm_sensor_v4l2_s_ctrl,
 	.queryctrl = msm_sensor_v4l2_query_ctrl,
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
 };
 
 static struct v4l2_subdev_video_ops mt9m114_subdev_video_ops = {
@@ -1298,12 +1266,9 @@
 	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
 	.sensor_mode_init = msm_sensor_mode_init,
 	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = mt9m114_sensor_config,
-	.sensor_open_init = mt9m114_sensor_open_init,
-	.sensor_release = mt9m114_sensor_release,
+	.sensor_config = msm_sensor_config,
 	.sensor_power_up = msm_sensor_power_up,
 	.sensor_power_down = msm_sensor_power_down,
-	.sensor_probe = msm_sensor_probe,
 };
 
 static struct msm_sensor_reg_t mt9m114_regs = {
diff --git a/drivers/media/video/msm/sensors/ov2720.c b/drivers/media/video/msm/sensors/ov2720.c
index 5938406..6389498 100644
--- a/drivers/media/video/msm/sensors/ov2720.c
+++ b/drivers/media/video/msm/sensors/ov2720.c
@@ -406,21 +406,6 @@
 	return 0;
 }
 
-static int ov2720_sensor_config(void __user *argp)
-{
-	return msm_sensor_config(&ov2720_s_ctrl, argp);
-}
-
-static int ov2720_sensor_open_init(const struct msm_camera_sensor_info *data)
-{
-	return msm_sensor_open_init(&ov2720_s_ctrl, data);
-}
-
-static int ov2720_sensor_release(void)
-{
-	return msm_sensor_release(&ov2720_s_ctrl);
-}
-
 static const struct i2c_device_id ov2720_i2c_id[] = {
 	{SENSOR_NAME, (kernel_ulong_t)&ov2720_s_ctrl},
 	{ }
@@ -438,31 +423,16 @@
 	.addr_type = MSM_CAMERA_I2C_WORD_ADDR,
 };
 
-static int ov2720_sensor_v4l2_probe(const struct msm_camera_sensor_info *info,
-	struct v4l2_subdev *sdev, struct msm_sensor_ctrl *s)
-{
-	return msm_sensor_v4l2_probe(&ov2720_s_ctrl, info, sdev, s);
-}
-
-static int ov2720_probe(struct platform_device *pdev)
-{
-	return msm_sensor_register(pdev, ov2720_sensor_v4l2_probe);
-}
-
-struct platform_driver ov2720_driver = {
-	.probe = ov2720_probe,
-	.driver = {
-		.name = PLATFORM_DRIVER_NAME,
-		.owner = THIS_MODULE,
-	},
-};
-
 static int __init msm_sensor_init_module(void)
 {
-	return platform_driver_register(&ov2720_driver);
+	return i2c_add_driver(&ov2720_i2c_driver);
 }
 
-static struct v4l2_subdev_core_ops ov2720_subdev_core_ops;
+static struct v4l2_subdev_core_ops ov2720_subdev_core_ops = {
+	.ioctl = msm_sensor_subdev_ioctl,
+	.s_power = msm_sensor_power,
+};
+
 static struct v4l2_subdev_video_ops ov2720_subdev_video_ops = {
 	.enum_mbus_fmt = msm_sensor_v4l2_enum_fmt,
 };
@@ -484,12 +454,9 @@
 	.sensor_set_sensor_mode = msm_sensor_set_sensor_mode,
 	.sensor_mode_init = msm_sensor_mode_init,
 	.sensor_get_output_info = msm_sensor_get_output_info,
-	.sensor_config = ov2720_sensor_config,
-	.sensor_open_init = ov2720_sensor_open_init,
-	.sensor_release = ov2720_sensor_release,
+	.sensor_config = msm_sensor_config,
 	.sensor_power_up = msm_sensor_power_up,
 	.sensor_power_down = msm_sensor_power_down,
-	.sensor_probe = msm_sensor_probe,
 };
 
 static struct msm_sensor_reg_t ov2720_regs = {