Пример #1
0
int msm_mctl_do_pp_divert(
    struct msm_cam_media_controller *p_mctl,
    int msg_type, struct msm_free_buf *fbuf,
    uint32_t frame_id, int pp_type)
{
    struct msm_cam_v4l2_dev_inst *pcam_inst;
    int idx, rc = 0;
    int del_buf = 0; /* delete from free queue */
    struct msm_cam_evt_divert_frame div;
    struct msm_frame_buffer *vb = NULL;
    struct videobuf2_contig_pmem *mem;

    idx = msm_mctl_out_type_to_inst_index(
              p_mctl->sync.pcam_sync, msg_type);
    pcam_inst = p_mctl->sync.pcam_sync->dev_inst[idx];
    vb = msm_mctl_buf_find(p_mctl, pcam_inst,
                           del_buf, msg_type, fbuf);
    if (!vb)
        return -EINVAL;
    vb->vidbuf.v4l2_buf.sequence = frame_id;
    mem = vb2_plane_cookie(&vb->vidbuf, 0);
    div.image_mode = pcam_inst->image_mode;
    div.op_mode    = pcam_inst->pcam->op_mode;
    div.inst_idx   = pcam_inst->my_index;
    div.node_idx   = pcam_inst->pcam->vnode_id;
    div.phy_addr   =
        videobuf2_to_pmem_contig(&vb->vidbuf, 0);
    div.phy_offset = mem->addr_offset;
    div.y_off      = 0;
    div.cbcr_off   = mem->offset.sp_off.cbcr_off;
    div.fd         = (int)mem->vaddr;
    div.vb = (uint32_t)vb;
    p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode]++;
    if (p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode] == 0)
        p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode]++;
    div.frame_id   =
        p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode];
    div.path       = mem->path;
    div.length     = mem->size;
    msm_mctl_gettimeofday(&div.timestamp);
    vb->vidbuf.v4l2_buf.timestamp = div.timestamp;
    div.do_pp = pp_type;
    if (!pp_type) {
        p_mctl->pp_info.div_frame[pcam_inst->image_mode].ch_paddr[0] =
            div.phy_addr;
    }
    rc = msm_mctl_pp_buf_divert(p_mctl, pcam_inst, &div);
    return rc;
}
/* called by the server or the config nodes to handle user space
	commands*/
static int msm_mctl_cmd(struct msm_cam_media_controller *p_mctl,
			unsigned int cmd, unsigned long arg)
{
	int rc = -EINVAL;
	void __user *argp = (void __user *)arg;
	if (!p_mctl) {
		pr_err("%s: param is NULL", __func__);
		return -EINVAL;
	}
	D("%s cmd = %d\n", __func__, _IOC_NR(cmd));

	/* ... call sensor, ISPIF or VEF subdev*/
	switch (cmd) {
		/* sensor config*/
	case MSM_CAM_IOCTL_GET_SENSOR_INFO:
			rc = msm_get_sensor_info(&p_mctl->sync, argp);
			break;

	case MSM_CAM_IOCTL_SENSOR_IO_CFG:
			rc = p_mctl->sync.sctrl.s_config(argp);
			break;

	case MSM_CAM_IOCTL_SENSOR_V4l2_S_CTRL: {
			struct v4l2_control v4l2_ctrl;
			CDBG("subdev call\n");
			if (copy_from_user(&v4l2_ctrl,
				(void *)argp,
				sizeof(struct v4l2_control))) {
				CDBG("copy fail\n");
				return -EFAULT;
			}
			CDBG("subdev call ok\n");
			rc = v4l2_subdev_call(p_mctl->sensor_sdev,
				core, s_ctrl, &v4l2_ctrl);
			break;
	}

	case MSM_CAM_IOCTL_SENSOR_V4l2_QUERY_CTRL: {
			struct v4l2_queryctrl v4l2_qctrl;
			CDBG("query called\n");
			if (copy_from_user(&v4l2_qctrl,
				(void *)argp,
				sizeof(struct v4l2_queryctrl))) {
				CDBG("copy fail\n");
				rc = -EFAULT;
				break;
			}
			rc = v4l2_subdev_call(p_mctl->sensor_sdev,
				core, queryctrl, &v4l2_qctrl);
			if (rc < 0) {
				rc = -EFAULT;
				break;
			}
			if (copy_to_user((void *)argp,
					 &v4l2_qctrl,
					 sizeof(struct v4l2_queryctrl))) {
				rc = -EFAULT;
			}
			break;
	}

	case MSM_CAM_IOCTL_ACTUATOR_IO_CFG: {
		struct msm_actuator_cfg_data act_data;
		if (p_mctl->sync.actctrl.a_config) {
			rc = p_mctl->sync.actctrl.a_config(argp);
		} else {
			rc = copy_from_user(
				&act_data,
				(void *)argp,
				sizeof(struct msm_actuator_cfg_data));
			if (rc != 0) {
				rc = -EFAULT;
				break;
			}
			act_data.is_af_supported = 0;
			rc = copy_to_user((void *)argp,
					 &act_data,
					 sizeof(struct msm_actuator_cfg_data));
			if (rc != 0) {
				rc = -EFAULT;
				break;
			}
		}
		break;
	}

	case MSM_CAM_IOCTL_GET_KERNEL_SYSTEM_TIME: {
		struct timeval timestamp;
		if (copy_from_user(&timestamp, argp, sizeof(timestamp))) {
			ERR_COPY_FROM_USER();
			rc = -EFAULT;
		} else {
			msm_mctl_gettimeofday(&timestamp);
			rc = copy_to_user((void *)argp,
				 &timestamp, sizeof(timestamp));
		}
		break;
	}

	case MSM_CAM_IOCTL_FLASH_CTRL: {
		struct flash_ctrl_data flash_info;
		if (copy_from_user(&flash_info, argp, sizeof(flash_info))) {
			ERR_COPY_FROM_USER();
			rc = -EFAULT;
		} else {
			rc = msm_flash_ctrl(p_mctl->sync.sdata, &flash_info);
		}
		break;
	}
	case MSM_CAM_IOCTL_PICT_PP:
		rc = msm_mctl_set_pp_key(p_mctl, (void __user *)arg);
		break;
	case MSM_CAM_IOCTL_PICT_PP_DIVERT_DONE:
		rc = msm_mctl_pp_divert_done(p_mctl, (void __user *)arg);
		break;
	case MSM_CAM_IOCTL_PICT_PP_DONE:
		rc = msm_mctl_pp_done(p_mctl, (void __user *)arg);
		break;
	case MSM_CAM_IOCTL_MCTL_POST_PROC:
		rc = msm_mctl_pp_ioctl(p_mctl, cmd, arg);
		break;
	case MSM_CAM_IOCTL_RESERVE_FREE_FRAME:
		rc = msm_mctl_pp_reserve_free_frame(p_mctl,
			(void __user *)arg);
		break;
	case MSM_CAM_IOCTL_RELEASE_FREE_FRAME:
		rc = msm_mctl_pp_release_free_frame(p_mctl,
			(void __user *)arg);
		break;
			/* ISFIF config*/
	default:
		/* ISP config*/
		rc = p_mctl->isp_sdev->isp_config(p_mctl, cmd, arg);
		break;
	}
	D("%s: !!! cmd = %d, rc = %d\n",
		__func__, _IOC_NR(cmd), rc);
	return rc;
}
int msm_mctl_do_pp_divert(
	struct msm_cam_media_controller *p_mctl,
	int msg_type, struct msm_free_buf *fbuf,
	uint32_t frame_id, int pp_type)
{
	struct msm_cam_v4l2_dev_inst *pcam_inst;
	int idx, rc = 0, i, buf_idx;
	int del_buf = 0; /* delete from free queue */
	struct msm_cam_evt_divert_frame div;
	struct msm_frame_buffer *vb = NULL;
	struct videobuf2_contig_pmem *mem;

	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];
	vb = msm_mctl_buf_find(p_mctl, pcam_inst,
		  del_buf, msg_type, fbuf);
	if (!vb)
		return -EINVAL;

	vb->vidbuf.v4l2_buf.sequence = frame_id;
	buf_idx = vb->vidbuf.v4l2_buf.index;
	div.image_mode = pcam_inst->image_mode;
	div.op_mode    = pcam_inst->pcam->op_mode;
	div.inst_idx   = pcam_inst->my_index;
	div.node_idx   = pcam_inst->pcam->vnode_id;
	p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode] = frame_id;
	div.frame.frame_id =
		p_mctl->pp_info.cur_frame_id[pcam_inst->image_mode];
#if defined(CONFIG_MSM_IOMMU)
	div.frame.buf_idx  = buf_idx;
#endif

	div.frame.handle = (uint32_t)vb;
	msm_mctl_gettimeofday(&div.frame.timestamp);
	vb->vidbuf.v4l2_buf.timestamp = div.frame.timestamp;
	div.do_pp = pp_type;
	/* Get the cookie for 1st plane and store the path.
	 * Also use this to check the number of planes in
	 * this buffer.*/
	mem = vb2_plane_cookie(&vb->vidbuf, 0);
	div.frame.path = mem->path;
#if defined(CONFIG_MSM_IOMMU)
	div.frame.node_type = VIDEO_NODE;
#endif

	if (mem->buffer_type == VIDEOBUF2_SINGLE_PLANE) {
		/* This buffer contains only 1 plane. Use the
		 * single planar structure to store the info.*/
		div.frame.num_planes	= 1;
		div.frame.sp.phy_addr	=
			videobuf2_to_pmem_contig(&vb->vidbuf, 0);
		div.frame.sp.addr_offset = mem->addr_offset;
		div.frame.sp.y_off      = 0;
		div.frame.sp.cbcr_off   = mem->offset.sp_off.cbcr_off;
		div.frame.sp.fd         = (int)mem->vaddr;
		div.frame.sp.length     = mem->size;
		if (!pp_type)
			p_mctl->pp_info.div_frame[pcam_inst->image_mode].
			ch_paddr[0] = div.frame.sp.phy_addr;
	} else {
		/* This buffer contains multiple planes. Use the mutliplanar
		 * structure to store the info. */
		div.frame.num_planes	= pcam_inst->plane_info.num_planes;
		/* Now traverse through all the planes of the buffer to
		 * fill out the plane info. */
		for (i = 0; i < div.frame.num_planes; i++) {
			mem = vb2_plane_cookie(&vb->vidbuf, i);
			div.frame.mp[i].phy_addr =
				videobuf2_to_pmem_contig(&vb->vidbuf, i);
			div.frame.mp[i].data_offset =
			pcam_inst->buf_offset[buf_idx][i].data_offset;
			div.frame.mp[i].addr_offset =
				mem->addr_offset;
			div.frame.mp[i].fd = (int)mem->vaddr;
			div.frame.mp[i].length = mem->size;
		}
		if (!pp_type)
			p_mctl->pp_info.div_frame[pcam_inst->image_mode].
			ch_paddr[0] = div.frame.mp[0].phy_addr;
	}
	rc = msm_mctl_pp_buf_divert(p_mctl, pcam_inst, &div);
	return rc;
}