static long msm_vpe_subdev_ioctl(struct v4l2_subdev *sd, unsigned int subdev_cmd, void *arg) { struct msm_mctl_pp_params *vpe_params; struct msm_mctl_pp_cmd *cmd; int rc = 0; if (subdev_cmd == VIDIOC_MSM_VPE_INIT) { struct msm_cam_media_controller *mctl = (struct msm_cam_media_controller *)arg; msm_vpe_subdev_init(sd, mctl); } else if (subdev_cmd == VIDIOC_MSM_VPE_RELEASE) { msm_vpe_subdev_release(); } else if (subdev_cmd == VIDIOC_MSM_VPE_CFG) { vpe_params = (struct msm_mctl_pp_params *)arg; cmd = vpe_params->cmd; switch (cmd->id) { case VPE_CMD_INIT: case VPE_CMD_DEINIT: break; case VPE_CMD_RESET: rc = vpe_reset(); break; case VPE_CMD_OPERATION_MODE_CFG: rc = vpe_operation_config(cmd->value); break; case VPE_CMD_INPUT_PLANE_CFG: vpe_input_plane_config(cmd->value); break; case VPE_CMD_OUTPUT_PLANE_CFG: vpe_output_plane_config(cmd->value); break; case VPE_CMD_SCALE_CFG_TYPE: vpe_update_scale_coef(cmd->value); break; case VPE_CMD_ZOOM: { rc = msm_vpe_do_pp(cmd, (struct msm_mctl_pp_frame_info *)vpe_params->data); break; } case VPE_CMD_ENABLE: { struct msm_vpe_clock_rate *clk_rate = cmd->value; int turbo_mode = (int)clk_rate->rate; rc = turbo_mode ? vpe_enable(VPE_TURBO_MODE_CLOCK_RATE) : vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE); break; } case VPE_CMD_DISABLE: rc = vpe_disable(); break; case VPE_CMD_INPUT_PLANE_UPDATE: case VPE_CMD_FLUSH: default: break; } CDBG("%s: end, id = %d, rc = %d", __func__, cmd->id, rc); } return rc; }
static int msm_vpe_process_vpe_cmd(struct msm_vpe_cfg_cmd *vpe_cmd, struct msm_cam_media_controller *mctl) { int rc = 0; switch (vpe_cmd->cmd_type) { case VPE_CMD_RESET: rc = vpe_reset(); break; case VPE_CMD_OPERATION_MODE_CFG: { struct msm_vpe_op_mode_cfg op_mode_cfg; if (sizeof(struct msm_vpe_op_mode_cfg) != vpe_cmd->length) { pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d", __func__, vpe_cmd->cmd_type, vpe_cmd->length, sizeof(struct msm_vpe_op_mode_cfg)); rc = -EINVAL; break; } COPY_FROM_USER(rc, &op_mode_cfg, (void __user *)vpe_cmd->value, sizeof(op_mode_cfg)); if (rc) { ERR_COPY_FROM_USER(); break; } vpe_cmd->value = (void *)&op_mode_cfg; rc = vpe_operation_config(vpe_cmd->value); break; } case VPE_CMD_INPUT_PLANE_CFG: { struct msm_vpe_input_plane_cfg input_cfg; if (sizeof(struct msm_vpe_input_plane_cfg) != vpe_cmd->length) { pr_err("%s: mismatch cmd = %d, len = %d, expected = %d", __func__, vpe_cmd->cmd_type, vpe_cmd->length, sizeof(struct msm_vpe_input_plane_cfg)); rc = -EINVAL; break; } COPY_FROM_USER(rc, &input_cfg, (void __user *)vpe_cmd->value, sizeof(input_cfg)); if (rc) { ERR_COPY_FROM_USER(); break; } vpe_cmd->value = (void *)&input_cfg; vpe_input_plane_config(vpe_cmd->value); break; } case VPE_CMD_OUTPUT_PLANE_CFG: { struct msm_vpe_output_plane_cfg output_cfg; if (sizeof(struct msm_vpe_output_plane_cfg) != vpe_cmd->length) { pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d", __func__, vpe_cmd->cmd_type, vpe_cmd->length, sizeof(struct msm_vpe_output_plane_cfg)); rc = -EINVAL; break; } COPY_FROM_USER(rc, &output_cfg, (void __user *)vpe_cmd->value, sizeof(output_cfg)); if (rc) { ERR_COPY_FROM_USER(); break; } vpe_cmd->value = (void *)&output_cfg; vpe_output_plane_config(vpe_cmd->value); break; } case VPE_CMD_SCALE_CFG_TYPE:{ struct msm_vpe_scaler_cfg scaler_cfg; if (sizeof(struct msm_vpe_scaler_cfg) != vpe_cmd->length) { pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d", __func__, vpe_cmd->cmd_type, vpe_cmd->length, sizeof(struct msm_vpe_scaler_cfg)); rc = -EINVAL; break; } COPY_FROM_USER(rc, &scaler_cfg, (void __user *)vpe_cmd->value, sizeof(scaler_cfg)); if (rc) { ERR_COPY_FROM_USER(); break; } vpe_cmd->value = (void *)&scaler_cfg; vpe_update_scale_coef(vpe_cmd->value); break; } case VPE_CMD_ZOOM: { struct msm_mctl_pp_frame_info *zoom; zoom = kmalloc(sizeof(struct msm_mctl_pp_frame_info), GFP_ATOMIC); if (!zoom) { pr_err("%s Not enough memory ", __func__); rc = -ENOMEM; break; } if (sizeof(zoom->pp_frame_cmd) != vpe_cmd->length) { pr_err("%s: size mismatch id=%d, len=%d, expected=%d", __func__, vpe_cmd->cmd_type, vpe_cmd->length, sizeof(zoom->pp_frame_cmd)); rc = -EINVAL; kfree(zoom); break; } COPY_FROM_USER(rc, &zoom->pp_frame_cmd, (void __user *)vpe_cmd->value, sizeof(zoom->pp_frame_cmd)); if (rc) { ERR_COPY_FROM_USER(); kfree(zoom); break; } zoom->user_cmd = vpe_cmd->cmd_type; zoom->p_mctl = v4l2_get_subdev_hostdata(&vpe_ctrl->subdev); D("%s: cookie=0x%x,action=0x%x,path=0x%x", __func__, zoom->pp_frame_cmd.cookie, zoom->pp_frame_cmd.vpe_output_action, zoom->pp_frame_cmd.path); D("%s Mapping Source frame ", __func__); zoom->src_frame.frame = zoom->pp_frame_cmd.src_frame; rc = msm_mctl_map_user_frame(&zoom->src_frame, zoom->p_mctl->client, mctl->domain_num); if (rc < 0) { pr_err("%s Error mapping source buffer rc = %d", __func__, rc); kfree(zoom); break; } D("%s Mapping Destination frame ", __func__); zoom->dest_frame.frame = zoom->pp_frame_cmd.dest_frame; rc = msm_mctl_map_user_frame(&zoom->dest_frame, zoom->p_mctl->client, mctl->domain_num); if (rc < 0) { pr_err("%s Error mapping dest buffer rc = %d", __func__, rc); msm_mctl_unmap_user_frame(&zoom->src_frame, zoom->p_mctl->client, mctl->domain_num); kfree(zoom); break; } rc = msm_vpe_do_pp(zoom); break; } case VPE_CMD_ENABLE: { struct msm_vpe_clock_rate clk_rate; int turbo_mode; if (sizeof(struct msm_vpe_clock_rate) != vpe_cmd->length) { pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d", __func__, vpe_cmd->cmd_type, vpe_cmd->length, sizeof(struct msm_vpe_clock_rate)); rc = -EINVAL; break; } if (copy_from_user(&clk_rate, (void __user *)vpe_cmd->value, sizeof(struct msm_vpe_clock_rate))) { pr_err("%s:clk_rate copy failed", __func__); return -EFAULT; } turbo_mode = (int)clk_rate.rate; rc = turbo_mode ? vpe_enable(VPE_TURBO_MODE_CLOCK_RATE, mctl) : vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE, mctl); break; } case VPE_CMD_DISABLE: #ifdef CONFIG_PANTECH_CAMERA if (vpe_ctrl->pp_frame_info) { pr_err("%s : vpe_ctrl->pp_frame_info = %p ", __func__, vpe_ctrl->pp_frame_info); msm_mctl_unmap_user_frame(&vpe_ctrl->pp_frame_info->src_frame, vpe_ctrl->pp_frame_info->p_mctl->client, mctl->domain_num); msm_mctl_unmap_user_frame(&vpe_ctrl->pp_frame_info->dest_frame, vpe_ctrl->pp_frame_info->p_mctl->client, mctl->domain_num); kfree(vpe_ctrl->pp_frame_info); vpe_ctrl->pp_frame_info = NULL; } #endif rc = vpe_disable(mctl); break; default: break; } return rc; }
static int msm_vpe_process_vpe_cmd(struct msm_vpe_cfg_cmd *vpe_cmd) { int rc = 0; switch (vpe_cmd->cmd_type) { case VPE_CMD_RESET: rc = vpe_reset(); break; case VPE_CMD_OPERATION_MODE_CFG: { struct msm_vpe_op_mode_cfg op_mode_cfg; if (sizeof(struct msm_vpe_op_mode_cfg) != vpe_cmd->length) { pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d", __func__, vpe_cmd->cmd_type, vpe_cmd->length, sizeof(struct msm_vpe_op_mode_cfg)); rc = -EINVAL; break; } COPY_FROM_USER(rc, &op_mode_cfg, (void __user *)vpe_cmd->value, sizeof(op_mode_cfg)); if (rc) { ERR_COPY_FROM_USER(); break; } vpe_cmd->value = (void *)&op_mode_cfg; rc = vpe_operation_config(vpe_cmd->value); break; } case VPE_CMD_INPUT_PLANE_CFG: { struct msm_vpe_input_plane_cfg input_cfg; if (sizeof(struct msm_vpe_input_plane_cfg) != vpe_cmd->length) { pr_err("%s: mismatch cmd = %d, len = %d, expected = %d", __func__, vpe_cmd->cmd_type, vpe_cmd->length, sizeof(struct msm_vpe_input_plane_cfg)); rc = -EINVAL; break; } COPY_FROM_USER(rc, &input_cfg, (void __user *)vpe_cmd->value, sizeof(input_cfg)); if (rc) { ERR_COPY_FROM_USER(); break; } vpe_cmd->value = (void *)&input_cfg; vpe_input_plane_config(vpe_cmd->value); break; } case VPE_CMD_OUTPUT_PLANE_CFG: { struct msm_vpe_output_plane_cfg output_cfg; if (sizeof(struct msm_vpe_output_plane_cfg) != vpe_cmd->length) { pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d", __func__, vpe_cmd->cmd_type, vpe_cmd->length, sizeof(struct msm_vpe_output_plane_cfg)); rc = -EINVAL; break; } COPY_FROM_USER(rc, &output_cfg, (void __user *)vpe_cmd->value, sizeof(output_cfg)); if (rc) { ERR_COPY_FROM_USER(); break; } vpe_cmd->value = (void *)&output_cfg; vpe_output_plane_config(vpe_cmd->value); break; } case VPE_CMD_SCALE_CFG_TYPE:{ struct msm_vpe_scaler_cfg scaler_cfg; if (sizeof(struct msm_vpe_scaler_cfg) != vpe_cmd->length) { pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d", __func__, vpe_cmd->cmd_type, vpe_cmd->length, sizeof(struct msm_vpe_scaler_cfg)); rc = -EINVAL; break; } COPY_FROM_USER(rc, &scaler_cfg, (void __user *)vpe_cmd->value, sizeof(scaler_cfg)); if (rc) { ERR_COPY_FROM_USER(); break; } vpe_cmd->value = (void *)&scaler_cfg; vpe_update_scale_coef(vpe_cmd->value); break; } case VPE_CMD_ZOOM: { struct msm_mctl_pp_frame_info *zoom; zoom = kmalloc(sizeof(struct msm_mctl_pp_frame_info), GFP_ATOMIC); if (!zoom) { pr_err("%s Not enough memory ", __func__); rc = -ENOMEM; break; } if (sizeof(zoom->pp_frame_cmd) != vpe_cmd->length) { pr_err("%s: size mismatch id=%d, len=%d, expected=%d", __func__, vpe_cmd->cmd_type, vpe_cmd->length, sizeof(zoom->pp_frame_cmd)); rc = -EINVAL; kfree(zoom); break; } COPY_FROM_USER(rc, &zoom->pp_frame_cmd, (void __user *)vpe_cmd->value, sizeof(zoom->pp_frame_cmd)); if (rc) { ERR_COPY_FROM_USER(); kfree(zoom); break; } zoom->user_cmd = vpe_cmd->cmd_type; zoom->p_mctl = v4l2_get_subdev_hostdata(&vpe_ctrl->subdev); D("%s: src=0x%x, dest=0x%x,cookie=0x%x,action=0x%x,path=0x%x", __func__, zoom->pp_frame_cmd.src_buf_handle, zoom->pp_frame_cmd.dest_buf_handle, zoom->pp_frame_cmd.cookie, zoom->pp_frame_cmd.vpe_output_action, zoom->pp_frame_cmd.path); rc = msm_mctl_pp_get_vpe_buf_info(zoom); if (rc < 0) { pr_err("%s Error getting buffer info from mctl rc = %d", __func__, rc); kfree(zoom); break; } rc = msm_vpe_do_pp(zoom); kfree(zoom); break; } case VPE_CMD_ENABLE: { struct msm_vpe_clock_rate clk_rate; int turbo_mode; if (sizeof(struct msm_vpe_clock_rate) != vpe_cmd->length) { pr_err("%s: size mismatch cmd=%d, len=%d, expected=%d", __func__, vpe_cmd->cmd_type, vpe_cmd->length, sizeof(struct msm_vpe_clock_rate)); rc = -EINVAL; break; } if (copy_from_user(&clk_rate, (void __user *)vpe_cmd->value, sizeof(struct msm_vpe_clock_rate))) { pr_err("%s:clk_rate copy failed", __func__); return -EFAULT; } turbo_mode = (int)clk_rate.rate; rc = turbo_mode ? vpe_enable(VPE_TURBO_MODE_CLOCK_RATE) : vpe_enable(VPE_NORMAL_MODE_CLOCK_RATE); break; } case VPE_CMD_DISABLE: rc = vpe_disable(); break; default: break; } return rc; }