/*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; }
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) {
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) {