Пример #1
0
static int vfe_7x_stop(void)
{
	int rc = 0;
	struct vfe_stop_t stopcmd;
	stopcmd.header = VFE_STOP_CMD;
	rc = msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
		&stopcmd, sizeof(struct vfe_stop_t));
	if(rc < 0)
		CDBG_ERR("%s:%d:Failed... rc = %d \n", __func__, __LINE__, rc);
	stopevent.state = 0;
	rc = wait_event_timeout(stopevent.wait,
		stopevent.state != 0,
		msecs_to_jiffies(stopevent.timeout));

	return rc;
}
static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
		void (*getevent)(void *ptr, size_t len))
{
	uint32_t evt_buf[3];
	void *data;
	struct buf_info *outch = NULL;
	uint32_t y_phy, cbcr_phy;
	struct table_cmd *table_pending = NULL;
	unsigned long flags;
	void   *cmd_data = NULL;
	unsigned char buf[256];
	struct msm_free_buf *free_buf = NULL;
	struct vfe_outputack fack;

	CDBG("%s:id=%d\n", __func__, id);

	if (id != VFE_ADSP_EVENT) {
		data = kzalloc(len, GFP_KERNEL);
		if (!data) {
			pr_err("%s: rp: cannot allocate buffer\n", __func__);
			return;
		}
	}
	if (id == VFE_ADSP_EVENT) {
		/* event */
		getevent(evt_buf, sizeof(evt_buf));
		CDBG("%s:event:msg_id=%d\n", __func__, id);
	} else {
		/* messages */
		getevent(data, len);
		CDBG("%s:messages:msg_id=%d\n", __func__, id);

		switch (id) {
		case MSG_SNAPSHOT:
			msm_camio_set_perf_lvl(S_PREVIEW);
			vfe_7x_ops(driver_data, MSG_OUTPUT_S, len, getevent);
			if (!raw_mode)
				vfe_7x_ops(driver_data, MSG_OUTPUT_T,
						len, getevent);
			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_SNAPSHOT_DONE);
			return;
		case MSG_OUTPUT_S:
			outch = &vfe2x_ctrl->snap;
			y_phy = outch->ping.ch_paddr[0];
			cbcr_phy = outch->ping.ch_paddr[1];
			CDBG("MSG_OUTPUT_S: %x %x\n",
				(unsigned int)y_phy, (unsigned int)cbcr_phy);
			vfe_send_outmsg(&vfe2x_ctrl->subdev, MSG_ID_OUTPUT_S,
							y_phy, cbcr_phy);
			break;
		case MSG_OUTPUT_T:
			outch = &vfe2x_ctrl->thumb;
			y_phy = outch->ping.ch_paddr[0];
			cbcr_phy = outch->ping.ch_paddr[1];
			CDBG("MSG_OUTPUT_T: %x %x\n",
				(unsigned int)y_phy, (unsigned int)cbcr_phy);
			vfe_send_outmsg(&vfe2x_ctrl->subdev, MSG_ID_OUTPUT_T,
							y_phy, cbcr_phy);
			break;
		case MSG_OUTPUT1:
		case MSG_OUTPUT2:
			if (op_mode & SNAPSHOT_MASK_MODE) {
				kfree(data);
				return;
			} else {
				free_buf = vfe2x_check_free_buffer(
					VFE_MSG_OUTPUT_IRQ,
					VFE_MSG_OUTPUT_P);
			      CDBG("free_buf = %x\n", (unsigned int) free_buf);
			      if (free_buf) {
					fack.header = VFE_OUTPUT2_ACK;

					fack.output2newybufferaddress =
						(void *)(free_buf->ch_paddr[0]);

					fack.output2newcbcrbufferaddress =
						(void *)(free_buf->ch_paddr[1]);

					cmd_data = &fack;
					len = sizeof(fack);
					msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
							cmd_data, len);
			      } else {
					fack.header = VFE_OUTPUT2_ACK;
					fack.output2newybufferaddress =
					(void *)
				((struct vfe_endframe *)data)->y_address;
					fack.output2newcbcrbufferaddress =
					(void *)
				((struct vfe_endframe *)data)->cbcr_address;
					cmd_data = &fack;
					len = sizeof(fack);
					msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
						cmd_data, len);
				}
			}
			y_phy = ((struct vfe_endframe *)data)->y_address;
			cbcr_phy = ((struct vfe_endframe *)data)->cbcr_address;


			CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
				 y_phy, cbcr_phy);

			memcpy(((struct vfe_frame_extra *)extdata),
				&((struct vfe_endframe *)data)->extra,
				sizeof(struct vfe_frame_extra));

			vfe2x_ctrl->vfeFrameId =
				((struct vfe_frame_extra *)extdata)->frame_id;
			vfe_send_outmsg(&vfe2x_ctrl->subdev,
							MSG_ID_OUTPUT_P,
							y_phy, cbcr_phy);
			break;
		case MSG_RESET_ACK:
		case MSG_START_ACK:
		case MSG_UPDATE_ACK:
		case MSG_VFE_ERROR:
		case MSG_SYNC_TIMER1_DONE:
		case MSG_SYNC_TIMER2_DONE:
			vfe2x_send_isp_msg(vfe2x_ctrl, msgs_map[id].isp_id);
			if (id == MSG_START_ACK)
				vfe2x_ctrl->vfe_started = 1;
			break;
		case MSG_SOF:
			vfe2x_ctrl->vfeFrameId++;
			if (vfe2x_ctrl->vfeFrameId == 0)
				vfe2x_ctrl->vfeFrameId = 1; /* wrapped back */
			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_SOF_ACK);
			if (raw_mode)
				vfe2x_send_isp_msg(vfe2x_ctrl,
						MSG_ID_START_ACK);
			break;
		case MSG_STOP_ACK:
			stopevent.state = 1;
			vfe2x_ctrl->vfe_started = 0;
			wake_up(&stopevent.wait);
			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_STOP_ACK);
			break;
		case MSG_STATS_AF:
		case MSG_STATS_WE:
			vfe_send_stats_msg(*(uint32_t *)data,
						msgs_map[id].isp_id);
			break;
		default:
			vfe2x_send_isp_msg(vfe2x_ctrl, msgs_map[id].isp_id);
			break;
		}
	}
	if (MSG_TABLE_CMD_ACK == id) {
		spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
		if (list_empty(&vfe2x_ctrl->table_q)) {
			if (vfe2x_ctrl->start_pending) {
				CDBG("Send START\n");
				cmd_data = buf;
				*(uint32_t *)cmd_data = VFE_START;
				memcpy(((char *)cmd_data) + 4,
					&vfe2x_ctrl->start_cmd,
					sizeof(vfe2x_ctrl->start_cmd));
				/* Send Start cmd here */
				len  = sizeof(vfe2x_ctrl->start_cmd) + 4;
				msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
						cmd_data, len);
				vfe2x_ctrl->start_pending = 0;
			}
			vfe2x_ctrl->tableack_pending = 0;
			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
			return;
		}
		table_pending = list_first_entry(&vfe2x_ctrl->table_q,
					struct table_cmd, list);
		if (!table_pending) {
			vfe2x_ctrl->tableack_pending = 0;
			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
			return;
		}
		msm_adsp_write(vfe_mod, table_pending->queue,
				table_pending->cmd, table_pending->size);
		list_del(&table_pending->list);
		kfree(table_pending->cmd);
		vfe2x_ctrl->tableack_pending = 1;
		spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
	} else if (!vfe2x_ctrl->tableack_pending) {
Пример #3
0
static int vfe_7x_config(struct msm_vfe_cfg_cmd_t *cmd, void *data)
{
	struct msm_pmem_region *regptr;
	unsigned char buf[256];

	struct vfe_stats_ack_t sack;
	struct axidata_t *axid;
	uint32_t i;

	struct vfe_stats_we_cfg_t *scfg_t = NULL;
	struct vfe_stats_af_cfg_t *sfcfg_t = NULL;
	struct axiout_t *axio = NULL;
	void   *cmd_data = NULL;
	void   *cmd_data_alloc = NULL;
	long rc = 0;
	struct msm_vfe_command_7k *vfecmd;

	vfecmd = kmalloc(sizeof(struct msm_vfe_command_7k),
				GFP_ATOMIC);
	if (!vfecmd) {
		CDBG_ERR("vfe_7x_config:vfecmd kmalloc fail\n");
		return -ENOMEM;
	}

	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(struct msm_vfe_command_7k))) {
			CDBG_ERR("vfe_7x_config:copy 0x%p ->0x%p fail LINE:%d\n",
				vfecmd->value,vfecmd,__LINE__);
			rc = -EFAULT;
			goto config_failure;
		}
	}

	switch (cmd->cmd_type) {
	case CMD_STATS_ENABLE:
	case CMD_STATS_AXI_CFG: {
		axid = data;
		if (!axid) {
			CDBG_ERR("vfe_7x_config:axid NULL pointer LINE:%d\n",__LINE__);
			rc = -EFAULT;
			goto config_failure;
		}

		scfg_t = kmalloc(sizeof(struct vfe_stats_we_cfg_t),
				GFP_ATOMIC);
		if (!scfg_t) {
			CDBG_ERR("vfe_7x_config:scfg_t kmalloc fail\n");
			rc = -ENOMEM;
			goto config_failure;
		}

		if (copy_from_user(scfg_t,
					(void __user *)(vfecmd->value),
					vfecmd->length)) {
			CDBG_ERR("vfe_7x_config:copy 0x%p ->0x%p fail LINE:%d\n",
				vfecmd->value,scfg_t,__LINE__);
			rc = -EFAULT;
			goto config_done;
		}

		CDBG("STATS_ENABLE: bufnum = %d, enabling = %d\n",
			axid->bufnum1, scfg_t->wb_expstatsenable);

		if (axid->bufnum1 > 0) {
			regptr = axid->region;

			for (i = 0; i < axid->bufnum1; i++) {

				CDBG("STATS_ENABLE, phy = 0x%lx\n",
					regptr->paddr);

				scfg_t->wb_expstatoutputbuffer[i] =
					(void *)regptr->paddr;
				regptr++;
			}

			cmd_data = scfg_t;

		} else {
			CDBG_ERR("vfe_7x_config:axid->bufnum1:%d\n",axid->bufnum1);
			rc = -EINVAL;
			goto config_done;
		}
		}
		break;

	case CMD_STATS_AF_ENABLE:
	case CMD_STATS_AF_AXI_CFG: {
		axid = data;
		if (!axid) {
			CDBG_ERR("vfe_7x_config:axid NULL pointer LINE:%d\n",__LINE__);
			rc = -EFAULT;
			goto config_failure;
		}

		sfcfg_t = kmalloc(sizeof(struct vfe_stats_af_cfg_t),
				GFP_ATOMIC);

		if (!sfcfg_t) {
			CDBG_ERR("vfe_7x_config:sfcfg_t kmalloc fail\n");
			rc = -ENOMEM;
			goto config_failure;
		}

		if (copy_from_user(sfcfg_t,
					(void __user *)(vfecmd->value),
					vfecmd->length)) {
			CDBG_ERR("vfe_7x_config:copy 0x%p ->0x%p fail LINE:%d\n",
				vfecmd->value,sfcfg_t,__LINE__);
			rc = -EFAULT;
			goto config_done;
		}

		CDBG("AF_ENABLE: bufnum = %d, enabling = %d\n",
			axid->bufnum1, sfcfg_t->af_enable);

		if (axid->bufnum1 > 0) {
			regptr = axid->region;

			for (i = 0; i < axid->bufnum1; i++) {

				CDBG("STATS_ENABLE, phy = 0x%lx\n",
					regptr->paddr);

				sfcfg_t->af_outbuf[i] =
					(void *)regptr->paddr;

				regptr++;
			}

			cmd_data = sfcfg_t;

		} else {
			CDBG_ERR("vfe_7x_config:axid->bufnum1:%d\n",axid->bufnum1);
			rc = -EINVAL;
			goto config_done;
		}
		}
		break;

	case CMD_FRAME_BUF_RELEASE: {
		struct msm_frame_t *b;
		unsigned long p;
		struct vfe_outputack_t fack;
		if (!data)  {
			CDBG_ERR("vfe_7x_config:data NULL pointer LINE:%d\n",__LINE__);
			rc = -EFAULT;
			goto config_failure;
		}

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

		fack.header = VFE_FRAME_ACK;

		fack.output2newybufferaddress =
			(void *)(p + b->y_off);

		fack.output2newcbcrbufferaddress =
			(void *)(p + b->cbcr_off);

		vfecmd->queue = QDSP_CMDQUEUE;
		vfecmd->length = sizeof(struct vfe_outputack_t);
		cmd_data = &fack;
	}
		break;

	case CMD_SNAP_BUF_RELEASE:
		break;

	case CMD_STATS_BUF_RELEASE: {
    		CDBG("vfe_7x_config: CMD_STATS_BUF_RELEASE\n");
		if (!data) {
			rc = -EFAULT;
			goto config_failure;
		}

		sack.header = STATS_WE_ACK;
		sack.bufaddr = (void *)*(uint32_t *)data;

		vfecmd->queue  = QDSP_CMDQUEUE;
		vfecmd->length = sizeof(struct vfe_stats_ack_t);
		cmd_data = &sack;
		}
		break;

	case CMD_STATS_AF_BUF_RELEASE: {
    		CDBG("vfe_7x_config: CMD_STATS_AF_BUF_RELEASE\n");
    		if (!data) {
			rc = -EFAULT;
			goto config_failure;
		}

		sack.header = STATS_AF_ACK;
		sack.bufaddr = (void *)*(uint32_t *)data;

		vfecmd->queue  = QDSP_CMDQUEUE;
		vfecmd->length = sizeof(struct vfe_stats_ack_t);
		cmd_data = &sack;
		}
		break;

	case CMD_GENERAL:
	case CMD_STATS_DISABLE: {
		if (vfecmd->length > 256) {
			cmd_data_alloc =
			cmd_data = kmalloc(vfecmd->length, GFP_ATOMIC);
			if (!cmd_data) {
				CDBG_ERR("vfe_7x_config:cmd_data kmalloc fail\n");
				rc = -ENOMEM;
				goto config_failure;
			}
		} else
			cmd_data = buf;

		if (copy_from_user(cmd_data,
					(void __user *)(vfecmd->value),
					vfecmd->length)) {
			CDBG_ERR("vfe_7x_config:copy 0x%p ->0x%p fail LINE:%d\n",
				vfecmd->value,cmd_data,__LINE__);
			rc = -EFAULT;
			goto config_done;
		}

		if (vfecmd->queue == QDSP_CMDQUEUE) {
			switch (*(uint32_t *)cmd_data) {
			case VFE_RESET_CMD:
				msm_camio_vfe_blk_reset();
				msm_camio_camif_pad_reg_reset_2();
				vfestopped = 0;
				CDBG("%s, VFE_RESET_CMD, vfestopped = %d\n", __func__  , vfestopped);
				break;

			case VFE_START_CMD:
				msm_camio_camif_pad_reg_reset_2();
				vfestopped = 0;
				CDBG("%s, VFE_START_CMD, vfestopped = %d\n", __func__  , vfestopped);
				break;

			case VFE_STOP_CMD:
				vfestopped = 1;
				CDBG("%s, VFE_STOP_CMD, vfestopped = %d\n", __func__  , vfestopped);
				goto config_send;
			default:
				break;
			}
		} /* QDSP_CMDQUEUE */
		}
		break;

	case CMD_AXI_CFG_OUT1: {
		axid = data;
		if (!axid) {
			CDBG_ERR("vfe_7x_config:axid NULL pointer LINE:%d\n",__LINE__);
			rc = -EFAULT;
			goto config_failure;
		}

		axio = kmalloc(sizeof(struct axiout_t), GFP_ATOMIC);
		if (!axio) {
			CDBG_ERR("vfe_7x_config:axio kmalloc fail\n");
			rc = -ENOMEM;
			goto config_failure;
		}

		if (copy_from_user(axio, (void *)(vfecmd->value),
					sizeof(struct axiout_t))) {
			CDBG_ERR("vfe_7x_config:copy 0x%p ->0x%p fail LINE:%d\n",
				vfecmd->value,axio,__LINE__);
			rc = -EFAULT;
			goto config_done;
		}

		vfe_7x_config_axi(OUTPUT_1, axid, axio);

		cmd_data = axio;
	}
		break;

	case CMD_AXI_CFG_OUT2:
	case CMD_RAW_PICT_AXI_CFG: {
		axid = data;
		if (!axid) {
			CDBG_ERR("vfe_7x_config:axid NULL pointer LINE:%d\n",__LINE__);
			rc = -EFAULT;
			goto config_failure;
		}

		axio = kmalloc(sizeof(struct axiout_t), GFP_ATOMIC);
		if (!axio) {
			CDBG_ERR("vfe_7x_config:axio kmalloc fail\n");
			rc = -ENOMEM;
			goto config_failure;
		}

		if (copy_from_user(axio, (void __user *)(vfecmd->value),
					sizeof(struct axiout_t))) {
			CDBG_ERR("vfe_7x_config:copy 0x%p ->0x%p fail LINE:%d\n",
				vfecmd->value,axio,__LINE__);
			rc = -EFAULT;
			goto config_done;
		}

		vfe_7x_config_axi(OUTPUT_2, axid, axio);
		cmd_data = axio;
		}
		break;

	case CMD_AXI_CFG_SNAP_O1_AND_O2: {
		axid = data;
		if (!axid) {
			CDBG_ERR("vfe_7x_config:axid NULL pointer LINE:%d\n",__LINE__);
			rc = -EFAULT;
			goto config_failure;
		}

		axio = kmalloc(sizeof(struct axiout_t), GFP_ATOMIC);
		if (!axio) {
			CDBG_ERR("vfe_7x_config:axio kmalloc fail\n");
			rc = -ENOMEM;
			goto config_failure;
		}

		if (copy_from_user(axio, (void __user *)(vfecmd->value),
					sizeof(struct axiout_t))) {
			CDBG_ERR("vfe_7x_config:copy 0x%p ->0x%p fail LINE:%d\n",
				vfecmd->value,axio,__LINE__);
			rc = -EFAULT;
			goto config_done;
		}

		vfe_7x_config_axi(OUTPUT_1_AND_2, axid, axio);
               CDBG("cmdheader = %d\n", axio->cmdheader);
               CDBG("outputmode = %d\n", axio->outputmode);
               CDBG("format = %d\n", axio->format);
               CDBG("out2yimageheight = %d\n", axio->out2yimageheight);
               CDBG("out2yimagewidthin64bitwords = %d\n", axio->out2yimagewidthin64bitwords);
               CDBG("out2yburstlen = %d\n", axio->out2yburstlen);
               CDBG("out2ynumrows = %d\n", axio->out2ynumrows);
               CDBG("out2yrowincin64bitincs = %d\n", axio->out2yrowincin64bitincs);
               CDBG("out2cbcrimageheight = %d\n", axio->out2cbcrimageheight);
               CDBG("out2cbcrimagewidtein64bitwords = %d\n", axio->out2cbcrimagewidtein64bitwords);
               CDBG("out2cbcrburstlen = %d\n", axio->out2cbcrburstlen);
               CDBG("out2cbcrnumrows = %d\n", axio->out2cbcrnumrows);
               CDBG("out2cbcrrowincin64bitincs = %d\n", axio->out2cbcrrowincin64bitincs);
               CDBG("output2buffer1_y_phy = %ld\n", axio->output2buffer1_y_phy);
               CDBG("output2buffer1_cbcr_phy = %ld\n", axio->output2buffer1_cbcr_phy);
               CDBG("output2buffer2_y_phy = %ld\n", axio->output2buffer2_y_phy);
               CDBG("output2buffer2_cbcr_phy = %ld\n", axio->output2buffer2_cbcr_phy);
               CDBG("output2buffer3_y_phy = %ld\n", axio->output2buffer3_y_phy);
               CDBG("output2buffer3_cbcr_phy = %ld\n", axio->output2buffer3_cbcr_phy);
               CDBG("output2buffer4_y_phy = %ld\n", axio->output2buffer4_y_phy);
               CDBG("output2buffer4_cbcr_phy = %ld\n", axio->output2buffer4_cbcr_phy);
               CDBG("output2buffer5_y_phy = %ld\n", axio->output2buffer5_y_phy);
		CDBG("output2buffer5_cbcr_phy = %ld\n", axio->output2buffer5_cbcr_phy);

		cmd_data = axio;
	}
		break;

	default:
		break;
	} /* switch */

	if (vfestopped)
		goto config_done;

config_send:
	CDBG("send adsp command = %d\n", *(uint32_t *)cmd_data);
	rc = msm_adsp_write(vfe_mod, vfecmd->queue,
				cmd_data, vfecmd->length);

config_done:
	if (cmd_data_alloc != NULL)
		kfree(cmd_data_alloc);

config_failure:
	kfree(scfg_t);
	kfree(sfcfg_t);
	kfree(axio);
	kfree(vfecmd);
	return rc;
}
Пример #4
0
static void vfe_7x_ops(void *driver_data, unsigned id, size_t len,
		void (*getevent)(void *ptr, size_t len))
{
	uint32_t evt_buf[3];
	void *data;
	struct buf_info *outch = NULL;
	uint32_t y_phy, cbcr_phy;
	struct table_cmd *table_pending = NULL;
	unsigned long flags;
	void   *cmd_data = NULL;
	unsigned char buf[256];
	struct msm_free_buf *free_buf = NULL;
	struct vfe_outputack fack;
	int i;

	CDBG("%s:id=%d\n", __func__, id);
	if (id != VFE_ADSP_EVENT) {
		data = kzalloc(len, GFP_KERNEL);
		if (!data) {
			pr_err("%s: rp: cannot allocate buffer\n", __func__);
			return;
		}
	}
	if (id == VFE_ADSP_EVENT) {
		
		getevent(evt_buf, sizeof(evt_buf));
		CDBG("%s:event:msg_id=%d\n", __func__, id);
	} else {
		
		getevent(data, len);
		CDBG("%s:messages:msg_id=%d\n", __func__, id);

		switch (id) {
		case MSG_SNAPSHOT:
			msm_camio_set_perf_lvl(S_PREVIEW);
			vfe_7x_ops(driver_data, MSG_OUTPUT_S, len, getevent);
			if (!raw_mode)
				vfe_7x_ops(driver_data, MSG_OUTPUT_T,
						len, getevent);
			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_SNAPSHOT_DONE);
			return;
		case MSG_OUTPUT_S:
			outch = &vfe2x_ctrl->snap;
			y_phy = outch->ping.ch_paddr[0];
			cbcr_phy = outch->ping.ch_paddr[1];
			CDBG("MSG_OUTPUT_S: %x %x\n",
				(unsigned int)y_phy, (unsigned int)cbcr_phy);
			vfe_send_outmsg(&vfe2x_ctrl->subdev,
					MSG_ID_OUTPUT_PRIMARY,
						y_phy, cbcr_phy);
			break;
		case MSG_OUTPUT_T:
			outch = &vfe2x_ctrl->thumb;
			y_phy = outch->ping.ch_paddr[0];
			cbcr_phy = outch->ping.ch_paddr[1];
			CDBG("MSG_OUTPUT_T: %x %x\n",
				(unsigned int)y_phy, (unsigned int)cbcr_phy);
			vfe_send_outmsg(&vfe2x_ctrl->subdev,
						MSG_ID_OUTPUT_SECONDARY,
							y_phy, cbcr_phy);
			break;
		case MSG_OUTPUT1:
			if (op_mode & SNAPSHOT_MASK_MODE) {
				kfree(data);
				return;
			} else {
				free_buf = vfe2x_check_free_buffer(
							VFE_MSG_OUTPUT_IRQ,
							VFE_MSG_OUTPUT_SECONDARY
							);
				CDBG("free_buf = %x\n",
						(unsigned int) free_buf);
				if (free_buf) {
					fack.header = VFE_OUTPUT1_ACK;

					fack.output2newybufferaddress =
						(void *)(free_buf->ch_paddr[0]);

					fack.output2newcbcrbufferaddress =
						(void *)(free_buf->ch_paddr[1]);

					cmd_data = &fack;
					len = sizeof(fack);
					msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
							cmd_data, len);
			      } else {
					fack.header = VFE_OUTPUT1_ACK;
					fack.output2newybufferaddress =
					(void *)
				((struct vfe_endframe *)data)->y_address;
					fack.output2newcbcrbufferaddress =
					(void *)
				((struct vfe_endframe *)data)->cbcr_address;
					cmd_data = &fack;
					len = sizeof(fack);
					msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
						cmd_data, len);
				}
			}
			y_phy = ((struct vfe_endframe *)data)->y_address;
			cbcr_phy = ((struct vfe_endframe *)data)->cbcr_address;


			CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
				 y_phy, cbcr_phy);
			if (free_buf) {
				for (i = 0; i < 3; i++) {
					if (vfe2x_ctrl->free_buf.buf[i].
							ch_paddr[0] == y_phy) {
						vfe2x_ctrl->free_buf.
							buf[i].ch_paddr[0] =
							free_buf->ch_paddr[0];
						vfe2x_ctrl->free_buf.
							buf[i].ch_paddr[1] =
							free_buf->ch_paddr[1];
						break;
					}
				}
				if (i == 3)
					CDBG("Address doesnt match\n");
			}
			memcpy(((struct vfe_frame_extra *)extdata),
				&((struct vfe_endframe *)data)->extra,
				sizeof(struct vfe_frame_extra));

			vfe2x_ctrl->vfeFrameId =
				((struct vfe_frame_extra *)extdata)->frame_id;
			vfe_send_outmsg(&vfe2x_ctrl->subdev,
						MSG_ID_OUTPUT_SECONDARY,
						y_phy, cbcr_phy);
			break;
		case MSG_OUTPUT2:
			if (op_mode & SNAPSHOT_MASK_MODE) {
				kfree(data);
				return;
			} else {
				free_buf = vfe2x_check_free_buffer(
					VFE_MSG_OUTPUT_IRQ,
					VFE_MSG_OUTPUT_PRIMARY);
			      CDBG("free_buf = %x\n", (unsigned int) free_buf);
			      if (free_buf) {
					fack.header = VFE_OUTPUT2_ACK;

					fack.output2newybufferaddress =
						(void *)(free_buf->ch_paddr[0]);

					fack.output2newcbcrbufferaddress =
						(void *)(free_buf->ch_paddr[1]);

					cmd_data = &fack;
					len = sizeof(fack);
					msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
							cmd_data, len);
			      } else {
					fack.header = VFE_OUTPUT2_ACK;
					fack.output2newybufferaddress =
					(void *)
				((struct vfe_endframe *)data)->y_address;
					fack.output2newcbcrbufferaddress =
					(void *)
				((struct vfe_endframe *)data)->cbcr_address;
					cmd_data = &fack;
					len = sizeof(fack);
					msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
						cmd_data, len);
				}
			}
			y_phy = ((struct vfe_endframe *)data)->y_address;
			cbcr_phy = ((struct vfe_endframe *)data)->cbcr_address;


			CDBG("vfe_7x_convert, y_phy = 0x%x, cbcr_phy = 0x%x\n",
				 y_phy, cbcr_phy);
			if (free_buf) {
				for (i = 0; i < 3; i++) {
					if (vfe2x_ctrl->free_buf.buf[i].
							ch_paddr[0] == y_phy) {
						vfe2x_ctrl->free_buf.
							buf[i].ch_paddr[0] =
							free_buf->ch_paddr[0];
						vfe2x_ctrl->free_buf.
							buf[i].ch_paddr[1] =
							free_buf->ch_paddr[1];
						break;
					}
				}
				if (i == 3)
					CDBG("Address doesnt match\n");
			}
			memcpy(((struct vfe_frame_extra *)extdata),
				&((struct vfe_endframe *)data)->extra,
				sizeof(struct vfe_frame_extra));

			vfe2x_ctrl->vfeFrameId =
				((struct vfe_frame_extra *)extdata)->frame_id;
			vfe_send_outmsg(&vfe2x_ctrl->subdev,
						MSG_ID_OUTPUT_PRIMARY,
						y_phy, cbcr_phy);
			break;
		case MSG_RESET_ACK:
		case MSG_START_ACK:
		case MSG_UPDATE_ACK:
		case MSG_VFE_ERROR:
		case MSG_SYNC_TIMER1_DONE:
		case MSG_SYNC_TIMER2_DONE:
			vfe2x_send_isp_msg(vfe2x_ctrl, msgs_map[id].isp_id);
			if (id == MSG_START_ACK)
				vfe2x_ctrl->vfe_started = 1;
			if (id == MSG_VFE_ERROR) {
				uint16_t *ptr;
				struct vfe_error_msg *VFE_ErrorMessageBuffer
					= data;
				ptr = data;
				CDBG("Error: %x %x\n", ptr[0], ptr[1]);
				CDBG("CAMIF_Error              = %d\n",
					VFE_ErrorMessageBuffer->camif_error);
				CDBG("output1YBusOverflow      = %d\n",
					VFE_ErrorMessageBuffer->
					output1ybusoverflow);
				CDBG("output1CbCrBusOverflow   = %d\n",
					VFE_ErrorMessageBuffer->
					output1cbcrbusoverflow);
				CDBG("output2YBusOverflow      = %d\n",
					VFE_ErrorMessageBuffer->
					output2ybusoverflow);
				CDBG("output2CbCrBusOverflow   = %d\n",
						VFE_ErrorMessageBuffer->
						output2cbcrbusoverflow);
				CDBG("autofocusStatBusOverflow = %d\n",
						VFE_ErrorMessageBuffer->
						autofocusstatbusoverflow);
				CDBG("WB_EXPStatBusOverflow    = %d\n",
						VFE_ErrorMessageBuffer->
						wb_expstatbusoverflow);
				CDBG("AXIError                 = %d\n",
						VFE_ErrorMessageBuffer->
						axierror);
				CDBG("CAMIF_Staus              = %d\n",
						VFE_ErrorMessageBuffer->
						camif_staus);
				CDBG("pixel_count              = %d\n",
						VFE_ErrorMessageBuffer->
						pixel_count);
				CDBG("line_count               = %d\n",
						VFE_ErrorMessageBuffer->
						line_count);
			}
			break;
		case MSG_SOF:
			vfe2x_ctrl->vfeFrameId++;
			if (vfe2x_ctrl->vfeFrameId == 0)
				vfe2x_ctrl->vfeFrameId = 1; 
			if ((op_mode & SNAPSHOT_MASK_MODE) && !raw_mode) {
				pr_err("Ignore SOF for snapshot\n");
				kfree(data);
				return;
			}
			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_SOF_ACK);
			if (raw_mode)
				vfe2x_send_isp_msg(vfe2x_ctrl,
						MSG_ID_START_ACK);
			break;
		case MSG_STOP_ACK:
			stopevent.state = 1;
			vfe2x_ctrl->vfe_started = 0;
			wake_up(&stopevent.wait);
			vfe2x_send_isp_msg(vfe2x_ctrl, MSG_ID_STOP_ACK);
			break;
		case MSG_STATS_AF:
		case MSG_STATS_WE:
			vfe_send_stats_msg(*(uint32_t *)data,
						msgs_map[id].isp_id);
			break;
		default:
			vfe2x_send_isp_msg(vfe2x_ctrl, msgs_map[id].isp_id);
			break;
		}
	}
	if (MSG_TABLE_CMD_ACK == id) {
		spin_lock_irqsave(&vfe2x_ctrl->table_lock, flags);
		vfe2x_ctrl->tableack_pending = 0;
		if (list_empty(&vfe2x_ctrl->table_q)) {
			if (vfe2x_ctrl->start_pending) {
				CDBG("Send START\n");
				cmd_data = buf;
				*(uint32_t *)cmd_data = VFE_START;
				memcpy(((char *)cmd_data) + 4,
					&vfe2x_ctrl->start_cmd,
					sizeof(vfe2x_ctrl->start_cmd));
				
				len  = sizeof(vfe2x_ctrl->start_cmd) + 4;
				msm_adsp_write(vfe_mod, QDSP_CMDQUEUE,
						cmd_data, len);
				vfe2x_ctrl->start_pending = 0;
			}
			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
			return;
		}
		table_pending = list_first_entry(&vfe2x_ctrl->table_q,
					struct table_cmd, list);
		if (!table_pending) {
			spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
			return;
		}
		msm_adsp_write(vfe_mod, table_pending->queue,
				table_pending->cmd, table_pending->size);
		list_del(&table_pending->list);
		kfree(table_pending->cmd);
		vfe2x_ctrl->tableack_pending = 1;
		spin_unlock_irqrestore(&vfe2x_ctrl->table_lock, flags);
	} else if (!vfe2x_ctrl->tableack_pending) {