msm: camera: Fix for camera crash
1. update get_sensor_info function to send sensor type
to the upper layers
2. update table ack pending flag in case of table ack
received
3. add ov5647 sensor power down function
Change-Id: I92c8e25d377d2fee09276b72119eb95adfcc79f8
Signed-off-by: Raju P.L.S.S.S.N <rplsssn@codeaurora.org>
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index 157c939..9080e60 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -461,6 +461,7 @@
.sensor_platform_info = &sensor_board_info_imx074,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
.actuator_info = &imx074_actuator_info
};
static struct msm_camera_csi_lane_params imx091_csi_lane_params = {
@@ -495,6 +496,7 @@
.sensor_platform_info = &sensor_board_info_imx091,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
};
static struct camera_vreg_t apq_8064_mt9m114_vreg[] = {
@@ -529,6 +531,7 @@
.sensor_platform_info = &sensor_board_info_mt9m114,
.csi_if = 1,
.camera_type = FRONT_CAMERA_2D,
+ .sensor_type = YUV_SENSOR,
};
static struct msm_camera_sensor_flash_data flash_ov2720 = {
@@ -556,6 +559,7 @@
.sensor_platform_info = &sensor_board_info_ov2720,
.csi_if = 1,
.camera_type = FRONT_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
};
void __init apq8064_init_cam(void)
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index 315e8fc..92e88aa72 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -446,6 +446,7 @@
.sensor_platform_info = &sensor_board_info_imx074,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
.actuator_info = &imx074_actuator_info
};
@@ -480,6 +481,7 @@
.sensor_platform_info = &sensor_board_info_mt9m114,
.csi_if = 1,
.camera_type = FRONT_CAMERA_2D,
+ .sensor_type = YUV_SENSOR,
};
static struct msm_camera_sensor_flash_data flash_ov2720 = {
@@ -506,6 +508,7 @@
.sensor_platform_info = &sensor_board_info_ov2720,
.csi_if = 1,
.camera_type = FRONT_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
};
static struct camera_vreg_t msm_8930_s5k3l1yx_vreg[] = {
@@ -539,6 +542,7 @@
.sensor_platform_info = &sensor_board_info_s5k3l1yx,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
};
void __init msm8930_init_cam(void)
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index d51a6d3..c2a378f 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -517,6 +517,7 @@
.sensor_platform_info = &sensor_board_info_imx074,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
.actuator_info = &imx074_actuator_info
};
@@ -551,6 +552,7 @@
.sensor_platform_info = &sensor_board_info_mt9m114,
.csi_if = 1,
.camera_type = FRONT_CAMERA_2D,
+ .sensor_type = YUV_SENSOR,
};
static struct msm_camera_sensor_flash_data flash_ov2720 = {
@@ -577,6 +579,7 @@
.sensor_platform_info = &sensor_board_info_ov2720,
.csi_if = 1,
.camera_type = FRONT_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
};
static struct camera_vreg_t msm_8960_s5k3l1yx_vreg[] = {
@@ -610,6 +613,7 @@
.sensor_platform_info = &sensor_board_info_s5k3l1yx,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
};
static struct msm_camera_csi_lane_params imx091_csi_lane_params = {
@@ -643,6 +647,7 @@
.sensor_platform_info = &sensor_board_info_imx091,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
};
static struct pm8xxx_mpp_config_data privacy_light_on_config = {
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index 608eb1e..2269073 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -149,6 +149,7 @@
.sensor_platform_info = &sensor_board_info_s5k4e1,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
#ifdef CONFIG_DW9712_ACT
.actuator_info = &s5k4e1_actuator_info
#endif
@@ -178,6 +179,7 @@
.sensor_platform_info = &sensor_board_info_ov7692,
.csi_if = 1,
.camera_type = FRONT_CAMERA_2D,
+ .sensor_type = YUV_SENSOR,
};
#endif
@@ -225,6 +227,7 @@
.sensor_platform_info = &sensor_board_info_ov5647,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
#ifdef CONFIG_AD5046_ACT
.actuator_info = &ad5046_actuator_info
@@ -254,6 +257,7 @@
.sensor_platform_info = &sensor_board_info_mt9e013,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
};
#endif
@@ -279,6 +283,7 @@
.sensor_platform_info = &sensor_board_info_ov9726,
.csi_if = 1,
.camera_type = FRONT_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
};
#endif
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index ae4d632..7b74f1e 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -172,6 +172,11 @@
BACK_CAMERA_INT_3D,
};
+enum msm_sensor_type {
+ BAYER_SENSOR,
+ YUV_SENSOR,
+};
+
enum camera_vreg_type {
REG_LDO,
REG_VS,
@@ -261,6 +266,7 @@
struct msm_camera_sensor_strobe_flash_data *strobe_flash_data;
char *eeprom_data;
enum msm_camera_type camera_type;
+ enum msm_sensor_type sensor_type;
struct msm_actuator_info *actuator_info;
int pmic_gpio_enable;
};
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 628fa62..001e02a 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -194,7 +194,8 @@
info.pxlcode = pcam->usr_fmts[0].pxlcode;
info.flashtype = sdata->flash_type; /* two flash_types here? */
info.camera_type = sdata->camera_type;
- info.sensor_type = 0; /* need to add YUV/SOC in probing */
+ /* sensor_type needed to add YUV/SOC in probing */
+ info.sensor_type = sdata->sensor_type;
info.mount_angle = sdata->sensor_platform_info->mount_angle;
/* copy back to user space */
if (copy_to_user((void *)arg,
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
index a332fba..af27a56 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.c
@@ -292,7 +292,8 @@
"VFE_DEMOSAICv3_BPC_UPDATE"},
{VFE_CMD_XBAR_CFG, VFE_MAX, VFE_MAX},
{VFE_CMD_MODULE_CFG, VFE_MAX, VFE_MAX},
- {VFE_CMD_ZSL, VFE_MAX, VFE_MAX},
+ {VFE_CMD_ZSL, VFE_START, QDSP_CMDQUEUE,
+ "VFE_CMD_ZSL", "VFE_START"},
{VFE_CMD_LINEARIZATION_UPDATE, VFE_MAX, VFE_MAX},
{VFE_CMD_DEMOSAICV3_ABF_UPDATE, VFE_DEMOSAICv3_ABF_CFG,
QDSP_TABLEQUEUE, "VFE_CMD_DEMOSAICV3_ABF_UPDATE",
@@ -452,6 +453,75 @@
y_phy, cbcr_phy);
break;
case MSG_OUTPUT1:
+ if (op_mode & SNAPSHOT_MASK_MODE) {
+ kfree(data);
+ return;
+ } else {
+ free_buf = vfe2x_check_free_buffer(
+ VFE_MSG_OUTPUT_IRQ,
+ VFE_MSG_OUTPUT_SECONDARY
+ );
+ CDBG("free_buf = %x\n",
+ (unsigned int) free_buf);
+ if (free_buf) {
+ fack.header = VFE_OUTPUT1_ACK;
+
+ fack.output2newybufferaddress =
+ (void *)(free_buf->ch_paddr[0]);
+
+ fack.output2newcbcrbufferaddress =
+ (void *)(free_buf->ch_paddr[1]);
+
+ cmd_data = &fack;
+ len = sizeof(fack);
+ msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+ cmd_data, len);
+ } else {
+ fack.header = VFE_OUTPUT1_ACK;
+ fack.output2newybufferaddress =
+ (void *)
+ ((struct vfe_endframe *)data)->y_address;
+ fack.output2newcbcrbufferaddress =
+ (void *)
+ ((struct vfe_endframe *)data)->cbcr_address;
+ cmd_data = &fack;
+ len = sizeof(fack);
+ msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
+ cmd_data, len);
+ }
+ }
+ y_phy = ((struct vfe_endframe *)data)->y_address;
+ cbcr_phy = ((struct vfe_endframe *)data)->cbcr_address;
+
+
+ CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
+ y_phy, cbcr_phy);
+ if (free_buf) {
+ for (i = 0; i < 3; i++) {
+ if (vfe2x_ctrl->free_buf.buf[i].
+ ch_paddr[0] == y_phy) {
+ vfe2x_ctrl->free_buf.
+ buf[i].ch_paddr[0] =
+ free_buf->ch_paddr[0];
+ vfe2x_ctrl->free_buf.
+ buf[i].ch_paddr[1] =
+ free_buf->ch_paddr[1];
+ break;
+ }
+ }
+ if (i == 3)
+ CDBG("Address doesnt match\n");
+ }
+ memcpy(((struct vfe_frame_extra *)extdata),
+ &((struct vfe_endframe *)data)->extra,
+ sizeof(struct vfe_frame_extra));
+
+ vfe2x_ctrl->vfeFrameId =
+ ((struct vfe_frame_extra *)extdata)->frame_id;
+ vfe_send_outmsg(&vfe2x_ctrl->subdev,
+ MSG_ID_OUTPUT_SECONDARY,
+ y_phy, cbcr_phy);
+ break;
case MSG_OUTPUT2:
if (op_mode & SNAPSHOT_MASK_MODE) {
kfree(data);
@@ -601,6 +671,7 @@
}
if (MSG_TABLE_CMD_ACK == id) {
spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
+ vfe2x_ctrl->tableack_pending = 0;
if (list_empty(&vfe2x_ctrl->table_q)) {
if (vfe2x_ctrl->start_pending) {
CDBG("Send START\n");
@@ -633,14 +704,12 @@
cmd_data, len);
vfe2x_ctrl->update_pending = 0;
}
- vfe2x_ctrl->tableack_pending = 0;
spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
return;
}
table_pending = list_first_entry(&vfe2x_ctrl->table_q,
struct table_cmd, list);
if (!table_pending) {
- vfe2x_ctrl->tableack_pending = 0;
spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
return;
}
@@ -673,16 +742,32 @@
if (mode == OUTPUT_SEC) {
/* Thumbnail */
- ao->output1buffer1_y_phy = ad->ping.ch_paddr[0];
- ao->output1buffer1_cbcr_phy = ad->ping.ch_paddr[1];
- ao->output1buffer2_y_phy = ad->pong.ch_paddr[0];
- ao->output1buffer2_cbcr_phy = ad->pong.ch_paddr[1];
- bptr = &ao->output1buffer3_y_phy;
- for (cnt = 0; cnt < 6; cnt++) {
- *bptr = ad->pong.ch_paddr[0];
- bptr++;
- *bptr = ad->pong.ch_paddr[1];
- bptr++;
+ if (vfe2x_ctrl->zsl_mode) {
+ ao->output2buffer1_y_phy = ad->ping.ch_paddr[0];
+ ao->output2buffer1_cbcr_phy = ad->ping.ch_paddr[1];
+ ao->output2buffer2_y_phy = ad->pong.ch_paddr[0];
+ ao->output2buffer2_cbcr_phy = ad->pong.ch_paddr[1];
+ ao->output2buffer3_y_phy = ad->free_buf.ch_paddr[0];
+ ao->output2buffer3_cbcr_phy = ad->free_buf.ch_paddr[1];
+ bptr = &ao->output2buffer4_y_phy;
+ for (cnt = 0; cnt < 5; cnt++) {
+ *bptr = ad->pong.ch_paddr[0];
+ bptr++;
+ *bptr = ad->pong.ch_paddr[1];
+ bptr++;
+ }
+ } else {
+ ao->output1buffer1_y_phy = ad->ping.ch_paddr[0];
+ ao->output1buffer1_cbcr_phy = ad->ping.ch_paddr[1];
+ ao->output1buffer2_y_phy = ad->pong.ch_paddr[0];
+ ao->output1buffer2_cbcr_phy = ad->pong.ch_paddr[1];
+ bptr = &ao->output1buffer3_y_phy;
+ for (cnt = 0; cnt < 6; cnt++) {
+ *bptr = ad->pong.ch_paddr[0];
+ bptr++;
+ *bptr = ad->pong.ch_paddr[1];
+ bptr++;
+ }
}
} else if (mode == OUTPUT_PRIM && o_mode != SNAPSHOT_MASK_MODE) {
/* Preview */
@@ -775,8 +860,13 @@
else if (path == VFE_MSG_OUTPUT_SECONDARY)
outch = &vfe2x_ctrl->thumb;
} else {
- if (path == VFE_MSG_OUTPUT_PRIMARY)
- outch = &vfe2x_ctrl->prev;
+ if (path == VFE_MSG_OUTPUT_PRIMARY) {
+ if (vfe2x_ctrl->zsl_mode)
+ outch = &vfe2x_ctrl->zsl_prim;
+ else
+ outch = &vfe2x_ctrl->prev;
+ } else if (path == VFE_MSG_OUTPUT_SECONDARY)
+ outch = &vfe2x_ctrl->zsl_sec;
}
if (outch->free_buf.ch_paddr[0])
return &outch->free_buf;
@@ -797,8 +887,13 @@
else if (path == VFE_MSG_OUTPUT_SECONDARY)
outch = &vfe2x_ctrl->thumb;
} else {
- if (path == VFE_MSG_OUTPUT_PRIMARY)
- outch = &vfe2x_ctrl->prev;
+ if (path == VFE_MSG_OUTPUT_PRIMARY) {
+ if (vfe2x_ctrl->zsl_mode)
+ outch = &vfe2x_ctrl->zsl_prim;
+ else
+ outch = &vfe2x_ctrl->prev;
+ } else if (path == VFE_MSG_OUTPUT_SECONDARY)
+ outch = &vfe2x_ctrl->zsl_sec;
}
if (outch->ping.ch_paddr[0] && outch->pong.ch_paddr[0]) {
/* Configure Preview Ping Pong */
@@ -823,8 +918,13 @@
else if (path == VFE_MSG_OUTPUT_PRIMARY)
ch = &vfe2x_ctrl->snap;
} else {
- if (path == VFE_MSG_OUTPUT_PRIMARY)
- ch = &vfe2x_ctrl->prev;
+ if (path == VFE_MSG_OUTPUT_PRIMARY) {
+ if (vfe2x_ctrl->zsl_mode)
+ ch = &vfe2x_ctrl->zsl_prim;
+ else
+ ch = &vfe2x_ctrl->prev;
+ } else if (path == VFE_MSG_OUTPUT_SECONDARY)
+ ch = &vfe2x_ctrl->zsl_sec;
}
BUG_ON(ch == NULL);
@@ -1121,6 +1221,7 @@
case VFE_CMD_START:
case VFE_CMD_CAPTURE:
case VFE_CMD_CAPTURE_RAW:
+ case VFE_CMD_ZSL:
spin_lock_irqsave(&vfe2x_ctrl->table_lock,
flags);
if ((!list_empty(&vfe2x_ctrl->table_q)) ||
@@ -1185,6 +1286,7 @@
case CMD_AXI_CFG_SEC: {
CDBG("CMD_AXI_CFG_SEC\n");
raw_mode = 0;
+ vfe2x_ctrl->zsl_mode = 0;
axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
if (!axio) {
pr_err("NULL axio\n");
@@ -1237,6 +1339,7 @@
case CMD_AXI_CFG_PRIM: {
CDBG("CMD_AXI_CFG_PRIM : %d\n", op_mode);
raw_mode = 0;
+ vfe2x_ctrl->zsl_mode = 0;
axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
if (!axio) {
pr_err("NULL axio\n");
@@ -1299,9 +1402,74 @@
cmd_data = axio;
}
break;
+ case CMD_AXI_CFG_ZSL: {
+ CDBG("CMD_AXI_CFG_ZSL: %d\n", op_mode);
+ raw_mode = 0;
+ vfe2x_ctrl->zsl_mode = 1;
+ axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
+ if (!axio) {
+ pr_err("NULL axio\n");
+ rc = -ENOMEM;
+ goto config_failure;
+ }
+
+ if (copy_from_user((char *)axio + 4,
+ (void __user *)(vfecmd.value),
+ sizeof(struct axiout))) {
+ pr_err("copy_from_user failed\n");
+ rc = -EFAULT;
+ goto config_done;
+ }
+ if (!vfe2x_ctrl->reconfig_vfe) {
+ rc = vfe2x_configure_pingpong_buffers(
+ VFE_MSG_V2X_PREVIEW,
+ VFE_MSG_OUTPUT_PRIMARY);
+ rc = vfe2x_configure_pingpong_buffers(
+ VFE_MSG_V2X_PREVIEW,
+ VFE_MSG_OUTPUT_SECONDARY);
+ if (rc < 0) {
+ pr_err("%s error configuring pingpong buffers"
+ " for preview", __func__);
+ rc = -EINVAL;
+ goto config_done;
+ }
+ free_buf = vfe2x_check_free_buffer(
+ VFE_MSG_OUTPUT_IRQ,
+ VFE_MSG_OUTPUT_PRIMARY);
+ free_buf = vfe2x_check_free_buffer(
+ VFE_MSG_OUTPUT_IRQ,
+ VFE_MSG_OUTPUT_SECONDARY);
+ } else {
+ vfe2x_ctrl->prev.ping.ch_paddr[0] =
+ vfe2x_ctrl->free_buf.buf[0].ch_paddr[0];
+ vfe2x_ctrl->prev.ping.ch_paddr[1] =
+ vfe2x_ctrl->free_buf.buf[0].ch_paddr[1];
+ vfe2x_ctrl->prev.pong.ch_paddr[0] =
+ vfe2x_ctrl->free_buf.buf[1].ch_paddr[0];
+ vfe2x_ctrl->prev.pong.ch_paddr[1] =
+ vfe2x_ctrl->free_buf.buf[1].ch_paddr[1];
+ vfe2x_ctrl->prev.free_buf.ch_paddr[0] =
+ vfe2x_ctrl->free_buf.buf[2].ch_paddr[0];
+ vfe2x_ctrl->prev.free_buf.ch_paddr[1] =
+ vfe2x_ctrl->free_buf.buf[2].ch_paddr[1];
+ vfe2x_ctrl->reconfig_vfe = 0;
+ }
+ header = cmds_map[vfecmd.id].vfe_id;
+ queue = cmds_map[vfecmd.id].queue;
+ if (header == -1 && queue == -1) {
+ rc = -EFAULT;
+ goto config_done;
+ }
+ *(uint32_t *)axio = header;
+ vfe_7x_config_axi(OUTPUT_PRIM, &vfe2x_ctrl->zsl_prim, axio);
+ vfe_7x_config_axi(OUTPUT_SEC, &vfe2x_ctrl->zsl_sec, axio);
+ cmd_data = axio;
+ }
+ break;
case CMD_AXI_CFG_SEC|CMD_AXI_CFG_PRIM: {
CDBG("CMD_AXI_CFG_SEC|PRIM\n");
raw_mode = 0;
+ vfe2x_ctrl->zsl_mode = 0;
axio = kmalloc(sizeof(struct axiout), GFP_ATOMIC);
if (!axio) {
pr_err("NULL axio\n");
@@ -1440,20 +1608,22 @@
spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
} else {
if (queue == QDSP_TABLEQUEUE) {
- CDBG("sending table cmd\n");
spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
+ CDBG("sending table cmd\n");
+ vfe2x_ctrl->tableack_pending = 1;
rc = msm_adsp_write(vfe_mod, queue,
cmd_data, vfecmd.length + 4);
- vfe2x_ctrl->tableack_pending = 1;
spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
} else {
- CDBG("send n-table cmd\n");
if (*(uint32_t *)cmd_data == VFE_OUTPUT2_ACK) {
uint32_t *ptr = cmd_data;
CDBG("%x %x %x\n", ptr[0], ptr[1], ptr[2]);
}
+ spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
+ CDBG("send n-table cmd\n");
rc = msm_adsp_write(vfe_mod, queue,
cmd_data, vfecmd.length + 4);
+ spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
CDBG("%x\n", vfecmd.length + 4);
}
}
diff --git a/drivers/media/video/msm/msm_vfe7x27a_v4l2.h b/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
index 2b77159..2f2d3c6 100644
--- a/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
+++ b/drivers/media/video/msm/msm_vfe7x27a_v4l2.h
@@ -85,6 +85,10 @@
struct buf_info raw;
struct buf_info thumb;
struct prev_free_buf_info free_buf;
+ struct buf_info zsl_prim;
+ struct buf_info zsl_sec;
+ struct prev_free_buf_info zsl_free_buf[2];
+
spinlock_t table_lock;
struct list_head table_q;
@@ -106,6 +110,7 @@
struct clk *vfe_clk[3];
spinlock_t sd_notify_lock;
uint32_t reconfig_vfe;
+ uint32_t zsl_mode;
} __packed;
struct vfe_frame_extra {
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index 1112be7..d882e52 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -214,59 +214,6 @@
return rc;
}
-int32_t msm_sensor_setting2(struct msm_sensor_ctrl_t *s_ctrl,
- int update_type, int res)
-{
- int32_t rc = 0;
- static int csi_config;
-
- s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
- if (csi_config == 0 || res == 0)
- msleep(66);
- else
- msleep(266);
- if (update_type == MSM_SENSOR_REG_INIT) {
- CDBG("Register INIT\n");
- s_ctrl->curr_csi_params = NULL;
- msm_camera_i2c_write(
- s_ctrl->sensor_i2c_client,
- 0x103, 0x1,
- MSM_CAMERA_I2C_BYTE_DATA);
- msm_sensor_enable_debugfs(s_ctrl);
- msm_sensor_write_init_settings(s_ctrl);
- csi_config = 0;
- } else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
- CDBG("PERIODIC : %d\n", res);
- msm_sensor_write_conf_array(
- s_ctrl->sensor_i2c_client,
- s_ctrl->msm_sensor_reg->mode_settings, res);
- msleep(30);
- if (!csi_config) {
- s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
- CDBG("CSI config in progress\n");
- v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
- NOTIFY_CSIC_CFG,
- s_ctrl->curr_csic_params);
- CDBG("CSI config is done\n");
- mb();
- msleep(30);
- csi_config = 1;
- msm_camera_i2c_write(
- s_ctrl->sensor_i2c_client,
- 0x100, 0x1,
- MSM_CAMERA_I2C_BYTE_DATA);
- }
- msm_camera_i2c_write(
- s_ctrl->sensor_i2c_client,
- 0x4800, 0x4,
- MSM_CAMERA_I2C_BYTE_DATA);
- msleep(266);
- s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
- msleep(50);
- }
- return rc;
-}
-
int32_t msm_sensor_setting1(struct msm_sensor_ctrl_t *s_ctrl,
int update_type, int res)
{
diff --git a/drivers/media/video/msm/sensors/ov5647_v4l2.c b/drivers/media/video/msm/sensors/ov5647_v4l2.c
index fed514c..9a85836 100644
--- a/drivers/media/video/msm/sensors/ov5647_v4l2.c
+++ b/drivers/media/video/msm/sensors/ov5647_v4l2.c
@@ -12,6 +12,7 @@
*/
#include "msm_sensor.h"
+#include "msm.h"
#define SENSOR_NAME "ov5647"
#define PLATFORM_DRIVER_NAME "msm_camera_ov5647"
#define ov5647_obj ov5647_##obj
@@ -333,27 +334,31 @@
, gain, line, line);
if (line > 1964) {
+ s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
- s_ctrl->sensor_exp_gain_info->vert_offset,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines,
(uint8_t)((line+4) >> 8),
MSM_CAMERA_I2C_BYTE_DATA);
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
- s_ctrl->sensor_exp_gain_info->vert_offset + 1,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
(uint8_t)((line+4) & 0x00FF),
MSM_CAMERA_I2C_BYTE_DATA);
+ s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
max_line = line + 4;
} else if (line > 1968) {
+ s_ctrl->func_tbl->sensor_group_hold_on(s_ctrl);
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
- s_ctrl->sensor_exp_gain_info->vert_offset,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines,
(uint8_t)((line+4) >> 8),
MSM_CAMERA_I2C_BYTE_DATA);
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
- s_ctrl->sensor_exp_gain_info->vert_offset + 1,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
(uint8_t)((line+4) & 0x00FF),
MSM_CAMERA_I2C_BYTE_DATA);
+ s_ctrl->func_tbl->sensor_group_hold_off(s_ctrl);
max_line = 1968;
}
@@ -447,24 +452,24 @@
if (line > 980) {
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
- s_ctrl->sensor_exp_gain_info->vert_offset,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines,
(uint8_t)((line+4) >> 8),
MSM_CAMERA_I2C_BYTE_DATA);
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
- s_ctrl->sensor_exp_gain_info->vert_offset + 1,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines + 1,
(uint8_t)((line+4) & 0x00FF),
MSM_CAMERA_I2C_BYTE_DATA);
max_line = line + 4;
} else if (line > 984) {
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
- s_ctrl->sensor_exp_gain_info->vert_offset,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines,
(uint8_t)(984 >> 8),
MSM_CAMERA_I2C_BYTE_DATA);
msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
- s_ctrl->sensor_exp_gain_info->vert_offset + 1 ,
+ s_ctrl->sensor_output_reg_addr->frame_length_lines + 1 ,
(uint8_t)(984 & 0x00FF),
MSM_CAMERA_I2C_BYTE_DATA);
max_line = 984;
@@ -568,33 +573,118 @@
.video = &ov5647_subdev_video_ops,
};
+int32_t ov5647_sensor_power_down(struct msm_sensor_ctrl_t *s_ctrl)
+{
+ struct msm_camera_sensor_info *info = NULL;
+ unsigned short rdata;
+ int rc;
+
+ info = s_ctrl->sensordata;
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ 0x4202, 0xf,
+ MSM_CAMERA_I2C_BYTE_DATA);
+ msleep(20);
+ rc = msm_camera_i2c_read(s_ctrl->sensor_i2c_client, 0x3018,
+ &rdata, MSM_CAMERA_I2C_WORD_DATA);
+ CDBG("ov5647_sensor_power_down: %d\n", rc);
+ rdata |= 0x18;
+ msm_camera_i2c_write(s_ctrl->sensor_i2c_client,
+ 0x3018, rdata,
+ MSM_CAMERA_I2C_WORD_DATA);
+ msleep(20);
+ gpio_direction_output(info->sensor_pwd, 1);
+ usleep_range(5000, 5100);
+ msm_sensor_power_down(s_ctrl);
+ return 0;
+}
+
int32_t ov5647_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
{
int32_t rc = 0;
struct msm_camera_sensor_info *info = NULL;
+ info = s_ctrl->sensordata;
+ gpio_direction_output(info->sensor_pwd, 1);
+ gpio_direction_output(info->sensor_reset, 0);
+ usleep_range(10000, 11000);
+ if (info->pmic_gpio_enable) {
+ info->pmic_gpio_enable = 0;
+ lcd_camera_power_onoff(1);
+ }
+ usleep_range(10000, 11000);
rc = msm_sensor_power_up(s_ctrl);
if (rc < 0) {
CDBG("%s: msm_sensor_power_up failed\n", __func__);
return rc;
}
- info = s_ctrl->sensordata;
- gpio_direction_output(info->sensor_pwd, 1);
- gpio_direction_output(info->sensor_reset, 0);
- usleep_range(1000, 1100);
/* turn on ldo and vreg */
- if (info->pmic_gpio_enable)
- lcd_camera_power_onoff(1);
gpio_direction_output(info->sensor_pwd, 0);
- usleep_range(4000, 4100);
+ msleep(20);
gpio_direction_output(info->sensor_reset, 1);
- usleep_range(2000, 2100);
+ msleep(25);
return rc;
}
+
+int32_t ov5647_sensor_setting(struct msm_sensor_ctrl_t *s_ctrl,
+ int update_type, int res)
+{
+ int32_t rc = 0;
+ static int csi_config;
+
+ s_ctrl->func_tbl->sensor_stop_stream(s_ctrl);
+ if (csi_config == 0 || res == 0)
+ msleep(66);
+ else
+ msleep(266);
+ msm_camera_i2c_write(
+ s_ctrl->sensor_i2c_client,
+ 0x4800, 0x25,
+ MSM_CAMERA_I2C_BYTE_DATA);
+ if (update_type == MSM_SENSOR_REG_INIT) {
+ CDBG("Register INIT\n");
+ s_ctrl->curr_csi_params = NULL;
+ msm_camera_i2c_write(
+ s_ctrl->sensor_i2c_client,
+ 0x103, 0x1,
+ MSM_CAMERA_I2C_BYTE_DATA);
+ msm_sensor_enable_debugfs(s_ctrl);
+ msm_sensor_write_init_settings(s_ctrl);
+ csi_config = 0;
+ } else if (update_type == MSM_SENSOR_UPDATE_PERIODIC) {
+ CDBG("PERIODIC : %d\n", res);
+ msm_sensor_write_conf_array(
+ s_ctrl->sensor_i2c_client,
+ s_ctrl->msm_sensor_reg->mode_settings, res);
+ msleep(30);
+ if (!csi_config) {
+ s_ctrl->curr_csic_params = s_ctrl->csic_params[res];
+ CDBG("CSI config in progress\n");
+ v4l2_subdev_notify(&s_ctrl->sensor_v4l2_subdev,
+ NOTIFY_CSIC_CFG,
+ s_ctrl->curr_csic_params);
+ CDBG("CSI config is done\n");
+ mb();
+ msleep(30);
+ csi_config = 1;
+ msm_camera_i2c_write(
+ s_ctrl->sensor_i2c_client,
+ 0x100, 0x1,
+ MSM_CAMERA_I2C_BYTE_DATA);
+ }
+ msm_camera_i2c_write(
+ s_ctrl->sensor_i2c_client,
+ 0x4800, 0x4,
+ MSM_CAMERA_I2C_BYTE_DATA);
+ msleep(266);
+ s_ctrl->func_tbl->sensor_start_stream(s_ctrl);
+ msleep(50);
+ }
+ return rc;
+}
static struct msm_sensor_fn_t ov5647_func_tbl = {
.sensor_start_stream = msm_sensor_start_stream,
.sensor_stop_stream = msm_sensor_stop_stream,
@@ -603,13 +693,13 @@
.sensor_set_fps = msm_sensor_set_fps,
.sensor_write_exp_gain = ov5647_write_prev_exp_gain,
.sensor_write_snapshot_exp_gain = ov5647_write_pict_exp_gain,
- .sensor_setting = msm_sensor_setting2,
+ .sensor_setting = ov5647_sensor_setting,
.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 = msm_sensor_config,
.sensor_power_up = ov5647_sensor_power_up,
- .sensor_power_down = msm_sensor_power_down,
+ .sensor_power_down = ov5647_sensor_power_down,
};
static struct msm_sensor_reg_t ov5647_regs = {