/*MTD-MM-SL-FixPreviewCurrent-00*{ */
static int vfe_7x_enable(struct camera_enable_cmd *enable)
{
	int rc = -EFAULT;

	if (!strcmp(enable->name, "QCAMTASK"))
		rc = msm_adsp_enable(qcam_mod);
	else if (!strcmp(enable->name, "VFETASK")){
		rc = msm_adsp_enable(vfe_mod);
		msm_camio_set_perf_lvl(S_INIT);
	}
	return rc;
}
Example #2
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];
	struct msm_vfe_resp *rp;
	void *data;
	CDBG("%s:id=%d\n", __func__, id);

	len = (id == VFE_ADSP_EVENT) ? 0 : len;
	data = resp->vfe_alloc(sizeof(struct msm_vfe_resp) + len,
		vfe_syncdata,  GFP_ATOMIC);

	if (!data) {
		pr_err("%s: rp: cannot allocate buffer\n", __func__);
		return;
	}
	rp = data;
	rp->evt_msg.len = len;

	if (id == VFE_ADSP_EVENT) {
		/* event */
		rp->type           = VFE_EVENT;
		rp->evt_msg.type   = MSM_CAMERA_EVT;
		getevent(evt_buf, sizeof(evt_buf));
		rp->evt_msg.msg_id = evt_buf[0];
		CDBG("%s:event:msg_id=%d\n", __func__, rp->evt_msg.msg_id);
		resp->vfe_resp(rp, MSM_CAM_Q_VFE_EVT, vfe_syncdata,
		GFP_ATOMIC);
	} else {
		/* messages */
		rp->evt_msg.type   = MSM_CAMERA_MSG;
		rp->evt_msg.msg_id = id;
		rp->evt_msg.data = rp + 1;
		getevent(rp->evt_msg.data, len);
		CDBG("%s:messages:msg_id=%d\n", __func__, rp->evt_msg.msg_id);

		switch (rp->evt_msg.msg_id) {
		case MSG_SNAPSHOT:
			msm_camio_set_perf_lvl(S_PREVIEW);
			vfe_7x_ops(driver_data, MSG_OUTPUT_S, len, getevent);
			vfe_7x_ops(driver_data, MSG_OUTPUT_T, len, getevent);
			rp->type = VFE_MSG_SNAPSHOT;
			break;
		case MSG_OUTPUT_S:
			rp->type = VFE_MSG_OUTPUT_S;
			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_S,
					rp->evt_msg.data, &(rp->extdata),
					&(rp->extlen));
			break;
		case MSG_OUTPUT_T:
			rp->type = VFE_MSG_OUTPUT_T;
			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_T,
					rp->evt_msg.data, &(rp->extdata),
					&(rp->extlen));
			break;
		case MSG_OUTPUT1:
		case MSG_OUTPUT2:
			if (op_mode & SNAPSHOT_MASK_MODE) {
				resp->vfe_free(data);
				return;
			}
			rp->type = VFE_MSG_OUTPUT_P;
			vfe_7x_convert(&(rp->phy), VFE_MSG_OUTPUT_P,
				rp->evt_msg.data, &(rp->extdata),
				&(rp->extlen));
			break;
		case MSG_STATS_AF:
			rp->type = VFE_MSG_STATS_AF;
			vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_AF,
					rp->evt_msg.data, NULL, NULL);
			break;
		case MSG_STATS_WE:
			rp->type = VFE_MSG_STATS_WE;
			vfe_7x_convert(&(rp->phy), VFE_MSG_STATS_WE,
					rp->evt_msg.data, NULL, NULL);

			CDBG("MSG_STATS_WE: phy = 0x%x\n", rp->phy.sbuf_phy);
			break;
		case MSG_STOP_ACK:
			rp->type = VFE_MSG_GENERAL;
			stopevent.state = 1;
			wake_up(&stopevent.wait);
			break;
		default:
			rp->type = VFE_MSG_GENERAL;
			break;
		}
		if (id != MSG_SOF)
			resp->vfe_resp(rp, MSM_CAM_Q_VFE_MSG,
					vfe_syncdata, GFP_ATOMIC);
	}
}
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) {
Example #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) {