diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h index 530d2c14856..700e28c4907 100644 --- a/arch/arm/mach-msm/include/mach/camera.h +++ b/arch/arm/mach-msm/include/mach/camera.h @@ -52,6 +52,7 @@ enum vfe_mode_of_operation{ VFE_MODE_OF_OPERATION_VIDEO, VFE_MODE_OF_OPERATION_RAW_SNAPSHOT, VFE_MODE_OF_OPERATION_ZSL, + VFE_MODE_OF_OPERATION_JPEG_SNAPSHOT, VFE_LAST_MODE_OF_OPERATION_ENUM }; @@ -87,6 +88,7 @@ enum vfe_resp_msg { VFE_MSG_V32_START, VFE_MSG_V32_START_RECORDING, /* 20 */ VFE_MSG_V32_CAPTURE, + VFE_MSG_V32_JPEG_CAPTURE, VFE_MSG_OUTPUT_IRQ, VFE_MSG_V2X_PREVIEW, VFE_MSG_V2X_CAPTURE, diff --git a/drivers/media/video/msm/msm_isp.c b/drivers/media/video/msm/msm_isp.c index c9a9f1bd3b2..16964b20382 100644 --- a/drivers/media/video/msm/msm_isp.c +++ b/drivers/media/video/msm/msm_isp.c @@ -199,6 +199,19 @@ static int msm_isp_notify_VFE_BUF_EVT(struct v4l2_subdev *sd, void *arg) vfe_params.data = (void *)&free_buf; rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params); break; + case VFE_MSG_V32_JPEG_CAPTURE: + free_buf.num_planes = 1; + free_buf.ch_paddr[0] = IMEM_Y_OFFSET; + free_buf.ch_paddr[1] = IMEM_CBCR_OFFSET; + cfgcmd.cmd_type = CMD_CONFIG_PING_ADDR; + cfgcmd.value = &vfe_id; + vfe_params.vfe_cfg = &cfgcmd; + vfe_params.data = (void *)&free_buf; + rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params); + /* Write the same buffer into PONG */ + cfgcmd.cmd_type = CMD_CONFIG_PONG_ADDR; + rc = v4l2_subdev_call(sd, core, ioctl, 0, &vfe_params); + break; case VFE_MSG_OUTPUT_IRQ: D("%s Got OUTPUT_IRQ: Getting free buf id = %d", __func__, vfe_id); diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c index 99d9911c6d0..89bdf0ffa7b 100644 --- a/drivers/media/video/msm/msm_vfe32.c +++ b/drivers/media/video/msm/msm_vfe32.c @@ -702,8 +702,6 @@ static void vfe32_start_common(void) msm_io_w(VFE_IMASK_WHILE_STOPPING_1, vfe32_ctrl->vfebase + VFE_IRQ_MASK_1); - msm_io_dump(vfe32_ctrl->vfebase, vfe32_ctrl->register_total * 4); - /* Ensure the write order while writing to the command register using the barrier */ msm_io_w_mb(1, vfe32_ctrl->vfebase + VFE_REG_UPDATE_CMD); @@ -851,7 +849,9 @@ static int vfe32_capture(uint32_t num_frames_capture) /* capture command is valid for both idle and active state. */ vfe32_ctrl->outpath.out1.capture_cnt = num_frames_capture; if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB || - vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) { + vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN || + vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB || + vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) { vfe32_ctrl->outpath.out0.capture_cnt = num_frames_capture; } @@ -887,6 +887,9 @@ static int vfe32_capture(uint32_t num_frames_capture) vfe32_AXI_WM_CFG[vfe32_ctrl->outpath.out1.ch1]); } } + + vfe32_ctrl->vfe_capture_count = num_frames_capture; + 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_bus_scale_cfg( @@ -1286,16 +1289,31 @@ static int vfe32_proc_general(struct msm_isp_cmd *cmd) rc = vfe32_capture_raw(snapshot_cnt); break; case VFE_CMD_CAPTURE: - pr_info("vfe32_proc_general: cmdID = %s\n", - vfe32_general_cmd[cmd->id]); + CDBG("vfe32_proc_general: cmdID = %s op mode = %d\n", + vfe32_general_cmd[cmd->id], vfe32_ctrl->operation_mode); if (copy_from_user(&snapshot_cnt, (void __user *)(cmd->value), sizeof(uint32_t))) { rc = -EFAULT; goto proc_general_done; } - /* Configure primary channel */ - rc = vfe32_configure_pingpong_buffers(VFE_MSG_V32_CAPTURE, - VFE_MSG_OUTPUT_PRIMARY); + + if (vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB || + vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) { + if (snapshot_cnt != 1) { + pr_err("only support 1 inline snapshot\n"); + rc = -EINVAL; + goto proc_general_done; + } + /* Configure primary channel for JPEG */ + rc = vfe32_configure_pingpong_buffers( + VFE_MSG_V32_JPEG_CAPTURE, + VFE_MSG_OUTPUT_PRIMARY); + } else { + /* Configure primary channel */ + rc = vfe32_configure_pingpong_buffers( + VFE_MSG_V32_CAPTURE, + VFE_MSG_OUTPUT_PRIMARY); + } if (rc < 0) { pr_err("%s error configuring pingpong buffers" " for primary output", __func__); @@ -2610,7 +2628,9 @@ static void vfe32_process_reg_update_irq(void) } if ((vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN) || - (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB)) { + (vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB) || + (vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG) || + (vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB)) { /* in snapshot mode */ /* later we need to add check for live snapshot mode. */ if (vfe32_ctrl->frame_skip_pattern & (0x1 << @@ -2858,6 +2878,8 @@ static void vfe32_process_output_path_irq_0(void) */ out_bool = ((vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_MAIN || vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB || + vfe32_ctrl->operation_mode == VFE_OUTPUTS_THUMB_AND_JPEG || + vfe32_ctrl->operation_mode == VFE_OUTPUTS_JPEG_AND_THUMB || vfe32_ctrl->operation_mode == VFE_OUTPUTS_RAW || vfe32_ctrl->liveshot_state == VFE_STATE_STARTED || vfe32_ctrl->liveshot_state == VFE_STATE_STOP_REQUESTED || @@ -2898,6 +2920,10 @@ static void vfe32_process_output_path_irq_0(void) VFE_OUTPUTS_THUMB_AND_MAIN || vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB || + vfe32_ctrl->operation_mode == + VFE_OUTPUTS_THUMB_AND_JPEG || + vfe32_ctrl->operation_mode == + VFE_OUTPUTS_JPEG_AND_THUMB || vfe32_ctrl->operation_mode == VFE_OUTPUTS_RAW || vfe32_ctrl->liveshot_state == VFE_STATE_STOPPED) @@ -3391,6 +3417,10 @@ static void vfe32_do_tasklet(unsigned long data) VFE_OUTPUTS_THUMB_AND_MAIN || vfe32_ctrl->operation_mode == VFE_OUTPUTS_MAIN_AND_THUMB || + vfe32_ctrl->operation_mode == + VFE_OUTPUTS_THUMB_AND_JPEG || + vfe32_ctrl->operation_mode == + VFE_OUTPUTS_JPEG_AND_THUMB || vfe32_ctrl->operation_mode == VFE_OUTPUTS_RAW) { if ((vfe32_ctrl->outpath.out0.capture_cnt == 0) diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h index 87fbbd216f9..1a6f68f7827 100644 --- a/include/media/msm_camera.h +++ b/include/media/msm_camera.h @@ -693,6 +693,9 @@ struct msm_stats_buf { #define MSM_V4L2_CAM_OP_ZSL (MSM_V4L2_CAM_OP_DEFAULT+4) /* camera operation mode for raw snapshot - one frame output queue */ #define MSM_V4L2_CAM_OP_RAW (MSM_V4L2_CAM_OP_DEFAULT+5) +/* camera operation mode for jpeg snapshot - one frame output queue */ +#define MSM_V4L2_CAM_OP_JPEG_CAPTURE (MSM_V4L2_CAM_OP_DEFAULT+6) + #define MSM_V4L2_VID_CAP_TYPE 0 #define MSM_V4L2_STREAM_ON 1 diff --git a/include/media/msm_isp.h b/include/media/msm_isp.h index 5dd1445c42a..07784e20df3 100644 --- a/include/media/msm_isp.h +++ b/include/media/msm_isp.h @@ -241,6 +241,9 @@ struct msm_isp_cmd { #define VPE_SCALER_CONFIG_LEN 260 #define VPE_DIS_OFFSET_CFG_LEN 12 +#define IMEM_Y_OFFSET 0x2E000000 +#define IMEM_CBCR_OFFSET 0x2E00FA00 + struct msm_vpe_op_mode_cfg { uint8_t op_mode_cfg[VPE_OPERATION_MODE_CFG_LEN]; }; @@ -311,6 +314,8 @@ struct msm_mctl_pp_frame_cmd { #define VFE_OUTPUTS_PREVIEW BIT(6) #define VFE_OUTPUTS_VIDEO BIT(7) #define VFE_OUTPUTS_RAW BIT(8) +#define VFE_OUTPUTS_JPEG_AND_THUMB BIT(9) +#define VFE_OUTPUTS_THUMB_AND_JPEG BIT(10) #endif /*__MSM_ISP_H__*/