Exemple #1
0
static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
{
	struct msm_pmem_region *regptr;
	struct msm_vfe_command_8k vfecmd;

	uint32_t i;

	void *cmd_data = NULL;
	long rc = 0;

	struct vfe_cmd_axi_output_config *axio = NULL;
	struct vfe_cmd_stats_setting *scfg = NULL;

	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
	    cmd->cmd_type != CMD_STATS_BUF_RELEASE) {

		if (copy_from_user(&vfecmd,
				(void __user *)(cmd->value),
				sizeof(struct msm_vfe_command_8k)))
			return -EFAULT;
	}

	CDBG("vfe_config: cmdType = %d\n", cmd->cmd_type);

	switch (cmd->cmd_type) {
	case CMD_GENERAL:
		rc = vfe_proc_general(&vfecmd);
		break;

	case CMD_STATS_ENABLE:
	case CMD_STATS_AXI_CFG: {
		struct axidata *axid;

		axid = data;
		if (!axid)
			return -EFAULT;

		scfg =
			kmalloc(sizeof(struct vfe_cmd_stats_setting),
				GFP_ATOMIC);
		if (!scfg)
			return -ENOMEM;

		if (copy_from_user(scfg,
					(void __user *)(vfecmd.value),
					vfecmd.length)) {

			kfree(scfg);
			return -EFAULT;
		}

		regptr = axid->region;
		if (axid->bufnum1 > 0) {
			for (i = 0; i < axid->bufnum1; i++) {
				scfg->awbBuffer[i] =
					(uint32_t)(regptr->paddr);
				regptr++;
			}
		}

		if (axid->bufnum2 > 0) {
			for (i = 0; i < axid->bufnum2; i++) {
				scfg->afBuffer[i] =
					(uint32_t)(regptr->paddr);
				regptr++;
			}
		}

		vfe_stats_config(scfg);
	}
		break;

	case CMD_STATS_AF_AXI_CFG: {
	}
		break;

	case CMD_FRAME_BUF_RELEASE: {
		/* preview buffer release */
		struct msm_frame *b;
		unsigned long p;
		struct vfe_cmd_output_ack fack;

		if (!data)
			return -EFAULT;

		b = (struct msm_frame *)(cmd->value);
		p = *(unsigned long *)data;

		b->path = MSM_FRAME_ENC;

		fack.ybufaddr[0] =
			(uint32_t)(p + b->y_off);

		fack.chromabufaddr[0] =
			(uint32_t)(p + b->cbcr_off);

		if (b->path == MSM_FRAME_PREV_1)
			vfe_output1_ack(&fack);

		if (b->path == MSM_FRAME_ENC ||
		    b->path == MSM_FRAME_PREV_2)
			vfe_output2_ack(&fack);
	}
		break;

	case CMD_SNAP_BUF_RELEASE: {
	}
		break;

	case CMD_STATS_BUF_RELEASE: {
		struct vfe_cmd_stats_wb_exp_ack sack;

		if (!data)
			return -EFAULT;

		sack.nextWbExpOutputBufferAddr = *(uint32_t *)data;
		vfe_stats_wb_exp_ack(&sack);
	}
		break;

	case CMD_AXI_CFG_OUT1: {
		struct axidata *axid;

		axid = data;
		if (!axid)
			return -EFAULT;

		axio = memdup_user((void __user *)(vfecmd.value),
				   sizeof(struct vfe_cmd_axi_output_config));
		if (IS_ERR(axio))
			return PTR_ERR(axio);

		vfe_config_axi(OUTPUT_1, axid, axio);
		vfe_axi_output_config(axio);
	}
		break;

	case CMD_AXI_CFG_OUT2:
	case CMD_RAW_PICT_AXI_CFG: {
		struct axidata *axid;

		axid = data;
		if (!axid)
			return -EFAULT;

		axio = memdup_user((void __user *)(vfecmd.value),
				   sizeof(struct vfe_cmd_axi_output_config));
		if (IS_ERR(axio))
			return PTR_ERR(axio);

		vfe_config_axi(OUTPUT_2, axid, axio);

		axio->outputDataSize = 0;
		vfe_axi_output_config(axio);
	}
		break;

	case CMD_AXI_CFG_SNAP_O1_AND_O2: {
		struct axidata *axid;
		axid = data;
		if (!axid)
			return -EFAULT;

		axio = memdup_user((void __user *)(vfecmd.value),
				   sizeof(struct vfe_cmd_axi_output_config));
		if (IS_ERR(axio))
			return PTR_ERR(axio);

		vfe_config_axi(OUTPUT_1_AND_2,
			axid, axio);
		vfe_axi_output_config(axio);
		cmd_data = axio;
	}
		break;

	default:
		break;
	} /* switch */

	kfree(scfg);

	kfree(axio);

/*
	if (cmd->length > 256 &&
			cmd_data &&
			(cmd->cmd_type == CMD_GENERAL ||
			 cmd->cmd_type == CMD_STATS_DISABLE)) {
		kfree(cmd_data);
	}
*/
	return rc;
}
static int vfe_config(struct msm_vfe_cfg_cmd *cmd, void *data)
{
	struct msm_pmem_region *regptr;
	struct msm_vfe_command_8k vfecmd;
	struct vfe_cmd_axi_output_config axio;
	struct axidata *axid = data;

	int rc = 0;

	if (cmd->cmd_type != CMD_FRAME_BUF_RELEASE &&
	    cmd->cmd_type != CMD_STATS_BUF_RELEASE &&
	    cmd->cmd_type != CMD_STATS_AF_BUF_RELEASE) {
		if (copy_from_user(&vfecmd,
				   (void __user *)(cmd->value), sizeof(vfecmd))) {
			ERR_COPY_FROM_USER();
			return -EFAULT;
		}
	}

	CDBG("%s: cmdType = %d\n", __func__, cmd->cmd_type);

	switch (cmd->cmd_type) {
	case CMD_GENERAL:
		rc = vfe_proc_general(&vfecmd);
		break;

	case CMD_STATS_ENABLE:
	case CMD_STATS_AXI_CFG: {
			int i;
			struct vfe_cmd_stats_setting scfg;

			BUG_ON(!axid);

			if (vfecmd.length != sizeof(scfg)) {
				pr_err
				    ("msm_camera: %s: cmd %d: user-space "\
				     "data size %d != kernel data size %d\n",
				     __func__,
				     cmd->cmd_type, vfecmd.length,
				     sizeof(scfg));
				return -EIO;
			}

			if (copy_from_user(&scfg,
					   (void __user *)(vfecmd.value),
					   sizeof(scfg))) {
				ERR_COPY_FROM_USER();
				return -EFAULT;
			}

			regptr = axid->region;
			if (axid->bufnum1 > 0) {
				for (i = 0; i < axid->bufnum1; i++) {
					scfg.awbBuffer[i] =
					    (uint32_t) (regptr->paddr);
					regptr++;
				}
			}

			if (axid->bufnum2 > 0) {
				for (i = 0; i < axid->bufnum2; i++) {
					scfg.afBuffer[i] =
					    (uint32_t) (regptr->paddr);
					regptr++;
				}
			}

			vfe_stats_setting(&scfg);
		}
		break;

	case CMD_STATS_AF_AXI_CFG:
		break;

	case CMD_FRAME_BUF_RELEASE: {
			/* preview buffer release */
			struct msm_frame *b;
			unsigned long p;
			struct vfe_cmd_output_ack fack;

			BUG_ON(!data);

			b = (struct msm_frame *)(cmd->value);
			p = *(unsigned long *)data;

			b->path = MSM_FRAME_ENC;

			fack.ybufaddr[0] = (uint32_t) (p + b->y_off);

			fack.chromabufaddr[0] = (uint32_t) (p + b->cbcr_off);

			if (b->path == MSM_FRAME_PREV_1)
				vfe_output1_ack(&fack);

			if (b->path == MSM_FRAME_ENC ||
			    b->path == MSM_FRAME_PREV_2)
				vfe_output2_ack(&fack);
		}
		break;

	case CMD_SNAP_BUF_RELEASE:
		break;

	case CMD_STATS_BUF_RELEASE: {
			struct vfe_cmd_stats_wb_exp_ack sack;

			BUG_ON(!data);

			sack.nextWbExpOutputBufferAddr = *(uint32_t *) data;
			vfe_stats_wb_exp_ack(&sack);
		}
		break;

	case CMD_STATS_AF_BUF_RELEASE: {
			struct vfe_cmd_stats_af_ack ack;

			BUG_ON(!data);

			ack.nextAFOutputBufferAddr = *(uint32_t *) data;
			vfe_stats_af_ack(&ack);
		}
		break;

	case CMD_AXI_CFG_OUT1: {

			BUG_ON(!axid);

			if (copy_from_user(&axio, (void __user *)(vfecmd.value),
					   sizeof(axio))) {
				ERR_COPY_FROM_USER();
				return -EFAULT;
			}

			vfe_config_axi(OUTPUT_1, axid, &axio);
			vfe_axi_output_config(&axio);
		}
		break;

	case CMD_AXI_CFG_OUT2:
	case CMD_RAW_PICT_AXI_CFG: {

			BUG_ON(!axid);

			if (copy_from_user(&axio, (void __user *)(vfecmd.value),
					   sizeof(axio))) {
				ERR_COPY_FROM_USER();
				return -EFAULT;
			}

			vfe_config_axi(OUTPUT_2, axid, &axio);

			axio.outputDataSize = 0;
			vfe_axi_output_config(&axio);
		}
		break;

	case CMD_AXI_CFG_SNAP_O1_AND_O2:{

			BUG_ON(!axid);

			if (copy_from_user(&axio, (void __user *)(vfecmd.value),
					   sizeof(axio))) {
				ERR_COPY_FROM_USER();
				return -EFAULT;
			}

			vfe_config_axi(OUTPUT_1_AND_2, axid, &axio);
			vfe_axi_output_config(&axio);
		}
		break;

	default:
		break;
	}			/* switch */

	return rc;
}