示例#1
0
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;
}
示例#2
0
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;
}