Beispiel #1
0
int msm_mctl_pp_reserve_free_frame(
	struct msm_cam_media_controller *p_mctl,
	void __user *arg)
{
	struct msm_cam_evt_divert_frame frame;
	int msg_type, image_mode, rc = 0;
	struct msm_free_buf free_buf;
	int idx;
	struct msm_cam_v4l2_dev_inst *pcam_inst;

	memset(&free_buf, 0, sizeof(struct msm_free_buf));
	if (copy_from_user(&frame, arg,
		sizeof(struct msm_cam_evt_divert_frame)))
		return -EFAULT;
	switch (frame.frame.path) {
	case OUTPUT_TYPE_P:
		msg_type = VFE_MSG_OUTPUT_P;
		image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
		break;
	case OUTPUT_TYPE_S:
		msg_type = VFE_MSG_OUTPUT_S;
		image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
		break;
	case OUTPUT_TYPE_V:
		msg_type = VFE_MSG_OUTPUT_V;
		image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
		break;
	case OUTPUT_TYPE_T:
	default:
		rc = -EFAULT;
		return rc;
	}

	idx = msm_mctl_out_type_to_inst_index(
		p_mctl->sync.pcam_sync, msg_type);
	if (idx < 0) {
		pr_err("%s Invalid instance. returning\n", __func__);
		return -EINVAL;
	}
	pcam_inst = p_mctl->sync.pcam_sync->dev_inst[idx];

	rc = msm_mctl_reserve_free_buf(p_mctl, msg_type, &free_buf);
	if (rc == 0) {
		msm_mctl_pp_get_phy_addr(pcam_inst, free_buf.vb, &frame.frame);
		if (copy_to_user((void *)arg,
				&frame,
				sizeof(frame))) {
			ERR_COPY_TO_USER();
			rc = -EFAULT;
		}
	}
	D("%s: reserve free buf, rc = %d, phy = 0x%x",
		__func__, rc, free_buf.ch_paddr[0]);
	return rc;
}
int msm_mctl_pp_proc_vpe_cmd(
	struct msm_cam_media_controller *p_mctl,
	struct msm_mctl_pp_cmd *pp_cmd)
{
	int rc = 0, idx;
	void __user *argp = (void __user *)pp_cmd->value;
	struct msm_cam_v4l2_dev_inst *pcam_inst;

	switch (pp_cmd->id) {
	case VPE_CMD_INIT:
	case VPE_CMD_DEINIT:
		rc = msm_isp_subdev_ioctl_vpe(
			p_mctl->isp_sdev->sd_vpe, pp_cmd, NULL);
		break;
	case VPE_CMD_DISABLE:
	case VPE_CMD_RESET:
		rc = msm_isp_subdev_ioctl_vpe(
			p_mctl->isp_sdev->sd_vpe, pp_cmd, NULL);
		break;
	case VPE_CMD_ENABLE: {
		struct msm_vpe_clock_rate clk_rate;
		if (sizeof(struct msm_vpe_clock_rate) !=
			pp_cmd->length) {
			D("%s: vpe cmd size mismatch "
				"(id=%d, length = %d, expect size = %d",
				__func__, pp_cmd->id, pp_cmd->length,
				sizeof(struct msm_vpe_clock_rate));
				rc = -EINVAL;
				break;
		}
		if (copy_from_user(&clk_rate, pp_cmd->value,
			sizeof(struct msm_vpe_clock_rate))) {
			D("%s:clk_rate copy failed", __func__);
			return -EFAULT;
		}
		pp_cmd->value = (void *)&clk_rate;
		rc = msm_isp_subdev_ioctl_vpe(
			p_mctl->isp_sdev->sd_vpe, pp_cmd, NULL);
		pp_cmd->value = argp;
		break;
	}
	case VPE_CMD_FLUSH: {
		struct msm_vpe_flush_frame_buffer flush_buf;
		if (sizeof(struct msm_vpe_flush_frame_buffer) !=
			pp_cmd->length) {
			D("%s: size mismatch(id=%d, len = %d, expected = %d",
				__func__, pp_cmd->id, pp_cmd->length,
				sizeof(struct msm_vpe_flush_frame_buffer));
				rc = -EINVAL;
				break;
		}
		if (copy_from_user(
			&flush_buf, pp_cmd->value, sizeof(flush_buf)))
			return -EFAULT;
		pp_cmd->value = (void *)&flush_buf;
		rc = msm_isp_subdev_ioctl_vpe(
			p_mctl->isp_sdev->sd_vpe, pp_cmd, NULL);
		if (rc == 0) {
			if (copy_to_user((void *)argp,
						&flush_buf,
						sizeof(flush_buf))) {
				ERR_COPY_TO_USER();
				rc = -EFAULT;
			}
			pp_cmd->value = argp;
		}
	}
	break;
	case VPE_CMD_OPERATION_MODE_CFG: {
		struct msm_vpe_op_mode_cfg_zsl op_mode_cfg;
		if (sizeof(struct msm_vpe_op_mode_cfg_zsl) !=
		pp_cmd->length) {
			D("%s: size mismatch(id=%d, len = %d, expected = %d",
				__func__, pp_cmd->id, pp_cmd->length,
				sizeof(struct msm_vpe_op_mode_cfg_zsl));
				rc = -EINVAL;
				break;
		}
		if (copy_from_user(&op_mode_cfg,
			pp_cmd->value,
			sizeof(op_mode_cfg)))
			return -EFAULT;
		pp_cmd->value = (void *)&op_mode_cfg;
		rc = msm_isp_subdev_ioctl_vpe(
			p_mctl->isp_sdev->sd_vpe, pp_cmd, NULL);
		break;
	}
	case VPE_CMD_INPUT_PLANE_CFG: {
		struct msm_vpe_input_plane_cfg input_cfg;
		if (sizeof(struct msm_vpe_input_plane_cfg) !=
			pp_cmd->length) {
			D("%s: mismatch(id=%d, len = %d, expected = %d",
				__func__, pp_cmd->id, pp_cmd->length,
				sizeof(struct msm_vpe_input_plane_cfg));
				rc = -EINVAL;
				break;
		}
		if (copy_from_user(
			&input_cfg, pp_cmd->value, sizeof(input_cfg)))
			return -EFAULT;
		pp_cmd->value = (void *)&input_cfg;
		rc = msm_isp_subdev_ioctl_vpe(
			p_mctl->isp_sdev->sd_vpe, pp_cmd, NULL);
		break;
	}
	case VPE_CMD_OUTPUT_PLANE_CFG: {
		struct msm_vpe_output_plane_cfg_zsl output_cfg;
		if (sizeof(struct msm_vpe_output_plane_cfg_zsl) !=
			pp_cmd->length) {
			D("%s: size mismatch(id=%d, len = %d, expected = %d",
				__func__, pp_cmd->id, pp_cmd->length,
				sizeof(struct msm_vpe_output_plane_cfg_zsl));
				rc = -EINVAL;
				break;
		}
		if (copy_from_user(&output_cfg, pp_cmd->value,
			sizeof(output_cfg))) {
			D("%s: cannot copy pp_cmd->value, size=%d",
				__func__, pp_cmd->length);
			return -EFAULT;
		}
		pp_cmd->value = (void *)&output_cfg;
		rc = msm_isp_subdev_ioctl_vpe(
			p_mctl->isp_sdev->sd_vpe, pp_cmd, NULL);
		break;
	}
	case VPE_CMD_INPUT_PLANE_UPDATE: {
		struct msm_vpe_input_plane_update_cfg input_update_cfg;
		if (sizeof(struct msm_vpe_input_plane_update_cfg) !=
			pp_cmd->length) {
			D("%s: size mismatch(id=%d, len = %d, expected = %d",
				__func__, pp_cmd->id, pp_cmd->length,
				sizeof(struct msm_vpe_input_plane_update_cfg));
				rc = -EINVAL;
				break;
		}
		if (copy_from_user(&input_update_cfg, pp_cmd->value,
			sizeof(input_update_cfg)))
			return -EFAULT;
		pp_cmd->value = (void *)&input_update_cfg;
		rc = msm_isp_subdev_ioctl_vpe(
			p_mctl->isp_sdev->sd_vpe, pp_cmd, NULL);
		break;
	}
	case VPE_CMD_SCALE_CFG_TYPE: {
		struct msm_vpe_scaler_cfg scaler_cfg;
		if (sizeof(struct msm_vpe_scaler_cfg) !=
			pp_cmd->length) {
			D("%s: size mismatch(id=%d, len = %d, expected = %d",
				__func__, pp_cmd->id, pp_cmd->length,
				sizeof(struct msm_vpe_scaler_cfg));
				rc = -EINVAL;
				break;
		}
		if (copy_from_user(&scaler_cfg, pp_cmd->value,
			sizeof(scaler_cfg)))
			return -EFAULT;
		pp_cmd->value = (void *)&scaler_cfg;
		rc = msm_isp_subdev_ioctl_vpe(
			p_mctl->isp_sdev->sd_vpe, pp_cmd, NULL);
		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) {
			rc = -ENOMEM;
			break;
		}
		if (sizeof(zoom->pp_frame_cmd) != pp_cmd->length) {
			D("%s: size mismatch(id=%d, len = %d, expected = %d",
				__func__, pp_cmd->id, pp_cmd->length,
				sizeof(zoom->pp_frame_cmd));
				rc = -EINVAL;
				kfree(zoom);
				break;
		}
		if (copy_from_user(&zoom->pp_frame_cmd, pp_cmd->value,
			sizeof(zoom->pp_frame_cmd))) {
			kfree(zoom);
			return -EFAULT;
		}
		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);
		idx = msm_mctl_pp_path_to_inst_index(p_mctl->sync.pcam_sync,
			zoom->pp_frame_cmd.path);
		if (idx < 0) {
			pr_err("%s Invalid path, returning\n", __func__);
			kfree(zoom);
			return idx;
		}
		pcam_inst = p_mctl->sync.pcam_sync->dev_inst[idx];
		if (!pcam_inst) {
			pr_err("%s Invalid instance, returning\n", __func__);
			kfree(zoom);
			return -EINVAL;
		}
		zoom->user_cmd = pp_cmd->id;
		rc = msm_mctl_pp_get_phy_addr(pcam_inst,
			zoom->pp_frame_cmd.src_buf_handle, &zoom->src_frame);
		if (rc) {
			kfree(zoom);
			break;
		}
		rc = msm_mctl_pp_get_phy_addr(pcam_inst,
			zoom->pp_frame_cmd.dest_buf_handle, &zoom->dest_frame);
		if (rc) {
			kfree(zoom);
			break;
		}
		rc = msm_mctl_pp_copy_timestamp_and_frame_id(
			zoom->pp_frame_cmd.src_buf_handle,

			zoom->pp_frame_cmd.dest_buf_handle);
		if (rc) {
			kfree(zoom);
			break;
		}
		rc = msm_isp_subdev_ioctl_vpe(
			p_mctl->isp_sdev->sd_vpe, pp_cmd, (void *)zoom);
		if (rc) {
			kfree(zoom);
			break;
		}
		break;
	}
	default:
		rc = -1;
		break;
	}
	return rc;
}