msm camera: snapshot wavelet denoise support
Signed-off-by: Mingcheng Zhu <mingchen@codeaurora.org>
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index 1babb9e..6dca569 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -193,7 +193,7 @@
}
/*send open command to server*/
-static int msm_send_open_server(void)
+static int msm_send_open_server(int vnode_id)
{
int rc = 0;
struct msm_ctrl_cmd ctrlcmd;
@@ -202,6 +202,7 @@
ctrlcmd.timeout_ms = 10000;
ctrlcmd.length = 0;
ctrlcmd.value = NULL;
+ ctrlcmd.vnode_id = vnode_id;
/* send command to config thread in usersspace, and get return value */
rc = msm_server_control(&g_server_dev, &ctrlcmd);
@@ -209,7 +210,7 @@
return rc;
}
-static int msm_send_close_server(void)
+static int msm_send_close_server(int vnode_id)
{
int rc = 0;
struct msm_ctrl_cmd ctrlcmd;
@@ -218,6 +219,7 @@
ctrlcmd.timeout_ms = 10000;
ctrlcmd.length = 0;
ctrlcmd.value = NULL;
+ ctrlcmd.vnode_id = vnode_id;
/* send command to config thread in usersspace, and get return value */
rc = msm_server_control(&g_server_dev, &ctrlcmd);
@@ -253,6 +255,7 @@
ctrlcmd.length = MSM_V4L2_DIMENSION_SIZE;
ctrlcmd.value = (void *)pfmt->fmt.pix.priv;
ctrlcmd.timeout_ms = 10000;
+ ctrlcmd.vnode_id = pcam->vnode_id;
/* send command to config thread in usersspace, and get return value */
rc = msm_server_control(&g_server_dev, &ctrlcmd);
@@ -591,13 +594,38 @@
{
int rc = 0;
struct msm_cam_v4l2_device *pcam = video_drvdata(f);
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ pcam_inst = container_of(f->private_data,
+ struct msm_cam_v4l2_dev_inst, eventHandle);
D("%s\n", __func__);
+
WARN_ON(pctx != f->private_data);
mutex_lock(&pcam->vid_lock);
- if (ctrl->id == MSM_V4L2_PID_CAM_MODE)
- pcam->op_mode = ctrl->value;
- rc = msm_server_s_ctrl(pcam, ctrl);
+ switch (ctrl->id) {
+ case MSM_V4L2_PID_MMAP_INST:
+ pr_err("%s: mmap_inst=(0x%p, %d)\n",
+ __func__, pcam_inst, pcam->remap_index);
+ pcam->remap_index = pcam_inst->my_index;
+ break;
+ case MSM_V4L2_PID_MMAP_ENTRY:
+ if (copy_from_user(&pcam->mmap_entry,
+ (void *)ctrl->value,
+ sizeof(pcam->mmap_entry))) {
+ rc = -EFAULT;
+ } else
+ pr_err("%s:mmap entry:phy=0x%x,image_mode=%d,op_mode=%d\n",
+ __func__, pcam->mmap_entry.phy_addr,
+ pcam->mmap_entry.image_mode,
+ pcam->mmap_entry.op_mode);
+
+ break;
+ default:
+ if (ctrl->id == MSM_V4L2_PID_CAM_MODE)
+ pcam->op_mode = ctrl->value;
+ rc = msm_server_s_ctrl(pcam, ctrl);
+ break;
+ }
mutex_unlock(&pcam->vid_lock);
return rc;
@@ -1311,7 +1339,7 @@
if (pcam->use_count == 1) {
- rc = msm_send_open_server();
+ rc = msm_send_open_server(pcam->vnode_id);
if (rc < 0) {
mutex_unlock(&pcam->vid_lock);
pr_err("%s failed\n", __func__);
@@ -1323,6 +1351,37 @@
return rc;
}
+static int msm_addr_remap(struct msm_cam_v4l2_dev_inst *pcam_inst,
+ struct vm_area_struct *vma,
+ struct msm_mmap_entry *entry)
+{
+ int phyaddr;
+ int retval;
+ unsigned long size;
+
+ phyaddr = (int)entry->phy_addr;
+ pr_err("%s: phy_addr=0x%x\n", __func__, (uint32_t)phyaddr);
+ size = vma->vm_end - vma->vm_start;
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ retval = remap_pfn_range(vma, vma->vm_start,
+ phyaddr >> PAGE_SHIFT,
+ size, vma->vm_page_prot);
+ if (retval) {
+ pr_err("%s:mmap: remap failed with error %d. ",
+ __func__, retval);
+ goto error;
+ }
+ pr_err("%s:mmap: phy_addr=0x%x: %08lx-%08lx, pgoff %08lx\n",
+ __func__, (uint32_t)phyaddr,
+ vma->vm_start, vma->vm_end, vma->vm_pgoff);
+ memset(entry, 0, sizeof(struct msm_mmap_entry));
+ return 0;
+error:
+ pr_err("%s:ret=%d\n", __func__, retval);
+ memset(entry, 0, sizeof(struct msm_mmap_entry));
+ return -ENOMEM;
+}
+
static int msm_mmap(struct file *f, struct vm_area_struct *vma)
{
int rc = 0;
@@ -1332,7 +1391,17 @@
D("mmap called, vma=0x%08lx\n", (unsigned long)vma);
- rc = vb2_mmap(&pcam_inst->vid_bufq, vma);
+ if (pcam_inst->pcam->remap_index ==
+ pcam_inst->my_index &&
+ pcam_inst->pcam->mmap_entry.phy_addr) {
+ pr_err("%s: ioremap called, vma=0x%08lx\n",
+ __func__, (unsigned long)vma);
+ rc = msm_addr_remap(pcam_inst, vma,
+ &pcam_inst->pcam->mmap_entry);
+ pr_err("%s: msm_addr_remap ret=%d\n", __func__, rc);
+ return rc;
+ } else
+ rc = vb2_mmap(&pcam_inst->vid_bufq, vma);
D("vma start=0x%08lx, size=%ld, ret=%d\n",
(unsigned long)vma->vm_start,
(unsigned long)vma->vm_end - (unsigned long)vma->vm_start,
@@ -1358,6 +1427,11 @@
mutex_lock(&pcam->vid_lock);
pcam->use_count--;
+ if (pcam_inst->pcam->remap_index ==
+ pcam_inst->my_index) {
+ pcam_inst->pcam->remap_index = 0;
+ memset(&pcam->mmap_entry, 0, sizeof(pcam->mmap_entry));
+ }
pcam->dev_inst_map[pcam_inst->image_mode] = NULL;
vb2_queue_release(&pcam_inst->vid_bufq);
pcam->dev_inst[pcam_inst->my_index] = NULL;
@@ -1381,7 +1455,7 @@
if (rc < 0)
pr_err("msm_cam_server_close_session fails %d\n", rc);
- rc = msm_send_close_server();
+ rc = msm_send_close_server(pcam->vnode_id);
if (rc < 0)
pr_err("msm_send_close_server failed %d\n", rc);
@@ -1689,7 +1763,8 @@
if (copy_from_user(&ev, (void __user *)arg,
sizeof(struct v4l2_event)))
break;
- u_isp_event = (struct msm_isp_stats_event_ctrl *)ev.u.data;
+ u_isp_event =
+ (struct msm_isp_stats_event_ctrl *)ev.u.data;
u_msg_value = u_isp_event->isp_data.isp_msg.data;
rc = v4l2_event_dequeue(
@@ -1699,21 +1774,24 @@
pr_err("no pending events?");
break;
}
-
- k_isp_event = (struct msm_isp_stats_event_ctrl *)ev.u.data;
- if (ev.type ==
- V4L2_EVENT_PRIVATE_START+MSM_CAM_RESP_STAT_EVT_MSG &&
- k_isp_event->isp_data.isp_msg.len > 0) {
- void *k_msg_value = k_isp_event->isp_data.isp_msg.data;
- if (copy_to_user(u_msg_value, k_msg_value,
- k_isp_event->isp_data.isp_msg.len)) {
- rc = -EINVAL;
- break;
+ if (ev.type != (V4L2_EVENT_PRIVATE_START +
+ MSM_CAM_RESP_DIV_FRAME_EVT_MSG)) {
+ k_isp_event =
+ (struct msm_isp_stats_event_ctrl *)ev.u.data;
+ if (ev.type == (V4L2_EVENT_PRIVATE_START +
+ MSM_CAM_RESP_STAT_EVT_MSG) &&
+ k_isp_event->isp_data.isp_msg.len > 0) {
+ void *k_msg_value =
+ k_isp_event->isp_data.isp_msg.data;
+ if (copy_to_user(u_msg_value, k_msg_value,
+ k_isp_event->isp_data.isp_msg.len)) {
+ rc = -EINVAL;
+ break;
+ }
+ kfree(k_msg_value);
}
- kfree(k_msg_value);
+ k_isp_event->isp_data.isp_msg.data = u_msg_value;
}
- k_isp_event->isp_data.isp_msg.data = u_msg_value;
-
if (copy_to_user((void __user *)arg, &ev,
sizeof(struct v4l2_event))) {
rc = -EINVAL;
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 15ed7fe..60172fc 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -94,6 +94,7 @@
struct msm_cam_v4l2_device;
struct msm_cam_v4l2_dev_inst;
+#define MSM_MAX_IMG_MODE 8
/* buffer for one video frame */
struct msm_frame_buffer {
@@ -139,6 +140,19 @@
extern int msm_ispif_init_module(struct msm_ispif_ops *p_ispif);
+struct msm_free_buf {
+ uint32_t paddr;
+ uint32_t y_off;
+ uint32_t cbcr_off;
+};
+
+struct msm_mctl_pp_info {
+ spinlock_t lock;
+ uint32_t cnt;
+ uint32_t pp_key;
+ uint32_t cur_frame_id[MSM_MAX_IMG_MODE];
+ struct msm_free_buf div_frame[MSM_MAX_IMG_MODE];
+};
/* "Media Controller" represents a camera steaming session,
* which consists of a "sensor" device and an "isp" device
* (such as VFE, if needed), connected via an "IO" device,
@@ -179,7 +193,7 @@
struct msm_ispif_fns *ispif_fns;
struct pm_qos_request_list pm_qos_req_list;
- uint32_t pp_key;
+ struct msm_mctl_pp_info pp_info;
};
/* abstract camera device represents a VFE and connected sensor */
@@ -206,11 +220,7 @@
unsigned long buffer;
int fd;
};
-struct msm_free_buf {
- uint32_t paddr;
- uint32_t y_off;
- uint32_t cbcr_off;
-};
+
#define MSM_DEV_INST_MAX 16
struct msm_cam_v4l2_dev_inst {
struct v4l2_fh eventHandle;
@@ -230,7 +240,6 @@
struct v4l2_crop crop;
int streamon;
};
-#define MSM_MAX_IMG_MODE 5
/* abstract camera device for each sensor successfully probed*/
struct msm_cam_v4l2_device {
/* standard device interfaces */
@@ -287,6 +296,8 @@
uint8_t ctrl_data[max_control_command_size];
struct msm_ctrl_cmd ctrl;
uint32_t event_mask;
+ struct msm_mmap_entry mmap_entry;
+ int remap_index;
};
static inline struct msm_cam_v4l2_device *to_pcam(
struct v4l2_device *v4l2_dev)
@@ -359,9 +370,7 @@
int msm_mctl_buf_done(struct msm_cam_media_controller *pmctl,
int msg_type, uint32_t y_phy, uint32_t frame_id);
int msm_mctl_buf_done_pp(struct msm_cam_media_controller *pmctl,
- int msg_type, uint32_t y_phy,
- uint32_t frame_id,
- struct timeval *timestamp);
+ int msg_type, struct msm_free_buf *frame, int dirty);
int msm_mctl_reserve_free_buf(struct msm_cam_media_controller *pmctl,
int path, struct msm_free_buf *free_buf);
int msm_mctl_release_free_buf(struct msm_cam_media_controller *pmctl,
diff --git a/drivers/media/video/msm/msm_mctl.c b/drivers/media/video/msm/msm_mctl.c
index 739d027..05b1742 100644
--- a/drivers/media/video/msm/msm_mctl.c
+++ b/drivers/media/video/msm/msm_mctl.c
@@ -204,40 +204,67 @@
static int msm_mctl_set_pp_key(struct msm_cam_media_controller *p_mctl,
void __user *arg)
{
- if (copy_from_user(&p_mctl->pp_key, arg, sizeof(p_mctl->pp_key)))
- return -EFAULT;
- return 0;
+ int rc = 0;
+ unsigned long flags;
+ spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
+ if (copy_from_user(&p_mctl->pp_info.pp_key,
+ arg, sizeof(p_mctl->pp_info.pp_key)))
+ rc = -EFAULT;
+ else
+ D("%s: mctl=0x%p, pp_key_setting=0x%x",
+ __func__, p_mctl, p_mctl->pp_info.pp_key);
+
+ spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
+ return rc;
}
static int msm_mctl_pp_done(struct msm_cam_media_controller *p_mctl,
void __user *arg)
{
- struct msm_buffer buf;
- int msg_type;
+ struct msm_frame frame;
+ int msg_type, image_mode, rc = 0;
+ int dirty = 0;
+ struct msm_free_buf buf;
+ unsigned long flags;
- if (copy_from_user(&buf, arg, sizeof(struct msm_buffer)))
+ if (copy_from_user(&frame, arg, sizeof(frame)))
return -EFAULT;
-
- switch (buf.path) {
+ spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
+ switch (frame.path) {
case OUTPUT_TYPE_P:
- if (!(p_mctl->pp_key & PP_PREV))
- return -EFAULT;
+ if (!(p_mctl->pp_info.pp_key & PP_PREV)) {
+ rc = -EFAULT;
+ goto err;
+ }
msg_type = VFE_MSG_OUTPUT_P;
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
break;
case OUTPUT_TYPE_S:
- if (!(p_mctl->pp_key & (PP_SNAP|PP_RAW_SNAP)))
+ if (!(p_mctl->pp_info.pp_key & PP_SNAP))
return -EFAULT;
msg_type = VFE_MSG_OUTPUT_S;
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
break;
case OUTPUT_TYPE_T:
case OUTPUT_TYPE_V:
default:
- return -EFAULT;
+ rc = -EFAULT;
+ goto err;
}
+ memcpy(&buf, &p_mctl->pp_info.div_frame[image_mode], sizeof(buf));
+ memset(&p_mctl->pp_info.div_frame[image_mode], 0, sizeof(buf));
+ if (p_mctl->pp_info.cur_frame_id[image_mode] !=
+ frame.frame_id) {
+ /* dirty frame. should not pass to app */
+ dirty = 1;
+ }
+ spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
/* here buf.addr is phy_addr */
- return msm_mctl_buf_done_pp(p_mctl, msg_type,
- buf.planes[0].addr,
- buf.frame_id, &buf.timestamp);
+ rc = msm_mctl_buf_done_pp(p_mctl, msg_type, &buf, dirty);
+ return rc;
+err:
+ spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
+ return rc;
}
/* called by the server or the config nodes to handle user space
@@ -479,6 +506,8 @@
pmctl->plat_dev = pcam->pdev;
/* init mctl buf */
msm_mctl_buf_init(pcam);
+ memset(&pmctl->pp_info, 0, sizeof(pmctl->pp_info));
+ spin_lock_init(&pmctl->pp_info.lock);
/* init sub device*/
v4l2_subdev_init(&(pmctl->mctl_sdev), &mctl_subdev_ops);
v4l2_set_subdevdata(&(pmctl->mctl_sdev), pmctl);
diff --git a/drivers/media/video/msm/msm_mctl_buf.c b/drivers/media/video/msm/msm_mctl_buf.c
index 1694ff7..361b612 100644
--- a/drivers/media/video/msm/msm_mctl_buf.c
+++ b/drivers/media/video/msm/msm_mctl_buf.c
@@ -429,7 +429,7 @@
struct msm_cam_media_controller *pmctl,
struct msm_cam_v4l2_dev_inst *pcam_inst,
int msg_type, uint32_t y_phy,
- uint32_t frame_id, struct timeval *timestamp)
+ uint32_t *frame_id, int gen_timestamp)
{
struct msm_frame_buffer *buf = NULL;
int del_buf = 1;
@@ -441,11 +441,12 @@
__func__, y_phy);
return -EINVAL;
}
- if (!timestamp)
+ if (gen_timestamp) {
+ if (frame_id)
+ buf->vidbuf.v4l2_buf.sequence = *frame_id;
msm_mctl_gettimeofday(
&buf->vidbuf.v4l2_buf.timestamp);
- else
- buf->vidbuf.v4l2_buf.timestamp = *timestamp;
+ }
vb2_buffer_done(&buf->vidbuf, VB2_BUF_STATE_DONE);
return 0;
}
@@ -453,31 +454,25 @@
static int msm_mctl_buf_divert(
struct msm_cam_media_controller *pmctl,
struct msm_cam_v4l2_dev_inst *pcam_inst,
- struct msm_buffer **buf)
+ struct msm_cam_evt_divert_frame *div)
{
struct v4l2_event v4l2_evt;
- struct msm_isp_stats_event_ctrl *isp_event;
-
+ struct msm_cam_evt_divert_frame *tmp;
memset(&v4l2_evt, 0, sizeof(v4l2_evt));
- isp_event =
- (struct msm_isp_stats_event_ctrl *)v4l2_evt.u.data;
- D("%s inst = %p, image_mode = %d, frame_id=%d\n",
- __func__, pcam_inst, pcam_inst->image_mode, (*buf)->frame_id);
v4l2_evt.type = V4L2_EVENT_PRIVATE_START +
- MSM_CAM_RESP_DIV_FRAME_EVT_MSG;
- isp_event->resptype = MSM_CAM_RESP_DIV_FRAME_EVT_MSG;
- isp_event->isp_data.div_frame.image_mode = pcam_inst->image_mode;
- isp_event->isp_data.div_frame.op_mode = pcam_inst->pcam->op_mode;
- isp_event->isp_data.div_frame.node_idx = pcam_inst->pcam->vnode_id;
- isp_event->isp_data.div_frame.inst_idx = pcam_inst->my_index;
- isp_event->isp_data.div_frame.len = sizeof(struct msm_buffer);
- isp_event->isp_data.div_frame.data = *buf;
- *buf = NULL;
- /* now queue the event */
- v4l2_event_queue(pmctl->config_device->config_stat_event_queue.pvdev,
- &v4l2_evt);
+ MSM_CAM_RESP_DIV_FRAME_EVT_MSG;
+ memcpy(&v4l2_evt.u.data[0], div,
+ sizeof(struct msm_cam_evt_divert_frame));
+ D("%s inst=%p, img_mode=%d, frame_id=%d,phy=0x%x,len=%d\n",
+ __func__, pcam_inst, pcam_inst->image_mode, div->frame_id,
+ (uint32_t)div->phy_addr, div->length);
+ tmp = (struct msm_cam_evt_divert_frame *)&v4l2_evt.u.data[0];
+ v4l2_event_queue(
+ pmctl->config_device->config_stat_event_queue.pvdev,
+ &v4l2_evt);
return 0;
}
+
int msm_mctl_buf_done(struct msm_cam_media_controller *p_mctl,
int msg_type, uint32_t y_phy, uint32_t frame_id)
{
@@ -485,80 +480,84 @@
struct msm_cam_v4l2_dev_inst *pcam_inst;
int idx;
int del_buf = 0;
+ int image_mode = MSM_V4L2_EXT_CAPTURE_MODE_DEFAULT;
+ unsigned long flags;
+ int path = 0;
+
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];
-
switch (msg_type) {
case VFE_MSG_OUTPUT_P:
pp_key = PP_PREV;
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
+ path = OUTPUT_TYPE_P;
break;
case VFE_MSG_OUTPUT_S:
pp_key = PP_SNAP;
+ image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
+ path = OUTPUT_TYPE_S;
break;
case VFE_MSG_OUTPUT_T:
- pp_key = OUTPUT_TYPE_T;
- break;
default:
+ path = OUTPUT_TYPE_T;
break;
}
- if (p_mctl->pp_key & pp_key) {
- /* need divert to pp */
- struct msm_buffer *buf;
+ spin_lock_irqsave(&p_mctl->pp_info.lock, flags);
+ if (p_mctl->pp_info.pp_key & pp_key) {
+ int rc = 0;
+ struct msm_cam_evt_divert_frame div;
struct msm_frame_buffer *vb = NULL;
struct videobuf2_contig_pmem *mem;
- buf = kmalloc(sizeof(struct msm_buffer), GFP_ATOMIC);
- if (!buf) {
- pr_err("%s:no mem\n", __func__);
- return -ENOMEM;
+ p_mctl->pp_info.cur_frame_id[image_mode]++;
+ if (!p_mctl->pp_info.cur_frame_id[image_mode])
+ p_mctl->pp_info.cur_frame_id[image_mode] = 1;
+ if (!p_mctl->pp_info.div_frame[image_mode].paddr) {
+ /* no frame in postproc. good to divert the frame up */
+ memset(&div, 0, sizeof(div));
+ vb = msm_mctl_buf_find(p_mctl, pcam_inst,
+ del_buf, msg_type, y_phy);
+ if (!vb) {
+ spin_unlock_irqrestore(&p_mctl->pp_info.lock,
+ flags);
+ 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 = mem->y_off;
+ div.cbcr_off = mem->cbcr_off;
+ div.fd = (int)mem->vaddr;
+ div.frame_id =
+ p_mctl->pp_info.cur_frame_id[image_mode];
+ div.path = path;
+ div.length = mem->size;
+ msm_mctl_gettimeofday(&div.timestamp);
+ vb->vidbuf.v4l2_buf.timestamp = div.timestamp;
+ p_mctl->pp_info.div_frame[image_mode].paddr =
+ div.phy_addr;
+ p_mctl->pp_info.div_frame[image_mode].y_off =
+ div.y_off;
+ p_mctl->pp_info.div_frame[image_mode].cbcr_off =
+ div.cbcr_off;
+ rc = msm_mctl_buf_divert(p_mctl, pcam_inst, &div);
+ spin_unlock_irqrestore(&p_mctl->pp_info.lock,
+ flags);
+ return rc;
}
- vb = msm_mctl_buf_find(p_mctl, pcam_inst,
- del_buf, msg_type, y_phy);
- if (!vb)
- return -EINVAL;
- mem = vb2_plane_cookie(&vb->vidbuf, 0);
- msm_mctl_gettimeofday(&buf->timestamp);
- buf->frame_id = frame_id;
- buf->path = mem->buffer_type;
- buf->num = 2;
- buf->memory_type = mem->is_userptr;
- buf->planes[0].type = MSM_PLANE_Y;
- buf->planes[0].offset = mem->y_off;
- buf->planes[0].length = mem->cbcr_off;
- buf->planes[0].addr =
- (unsigned long)videobuf2_to_pmem_contig(&vb->vidbuf, 0);
- buf->planes[0].addr_offset = mem->addr_offset;
- buf->planes[0].fd = (int)mem->vaddr;
- buf->planes[1].type = MSM_PLANE_UV;
- buf->planes[1].offset = mem->cbcr_off;
- /* this is a hack for single plane case.
- need cleanup when moving to rael multi-planner */
- buf->planes[1].length = mem->size;
- buf->planes[1].addr =
- (unsigned long)videobuf2_to_pmem_contig(&vb->vidbuf, 0);
- buf->planes[1].addr_offset = mem->addr_offset;
- buf->planes[1].fd = (int)mem->vaddr;
- return msm_mctl_buf_divert(p_mctl, pcam_inst, &buf);
- } else
- return msm_mctl_buf_done_proc(p_mctl, pcam_inst,
+ }
+ spin_unlock_irqrestore(&p_mctl->pp_info.lock, flags);
+ return msm_mctl_buf_done_proc(p_mctl, pcam_inst,
msg_type, y_phy,
- frame_id, NULL);
-}
-
-int msm_mctl_buf_done_pp(struct msm_cam_media_controller *pmctl,
- int msg_type, uint32_t y_phy,
- uint32_t frame_id, struct timeval *timestamp)
-{
- struct msm_cam_v4l2_dev_inst *pcam_inst;
- int idx;
-
- idx = msm_mctl_out_type_to_inst_index(
- pmctl->sync.pcam_sync, msg_type);
- pcam_inst = pmctl->sync.pcam_sync->dev_inst[idx];
- return msm_mctl_buf_done_proc(pmctl, pcam_inst,
- msg_type, y_phy, frame_id, timestamp);
+ &frame_id, 1);
}
int msm_mctl_buf_init(struct msm_cam_v4l2_device *pcam)
@@ -582,10 +581,12 @@
return rc;
}
memset(free_buf, 0, sizeof(struct msm_free_buf));
- idx = msm_mctl_out_type_to_inst_index(pmctl->sync.pcam_sync, msg_type);
+ idx = msm_mctl_out_type_to_inst_index(pmctl->sync.pcam_sync,
+ msg_type);
pcam_inst = pmctl->sync.pcam_sync->dev_inst[idx];
if (!pcam_inst->streamon) {
- pr_err("%s: stream 0x%p is off\n", __func__, pcam_inst);
+ pr_err("%s: stream 0x%p is off\n",
+ __func__, pcam_inst);
return rc;
}
spin_lock_irqsave(&pcam_inst->vq_irqlock, flags);
@@ -653,3 +654,24 @@
return rc;
}
+int msm_mctl_buf_done_pp(
+ struct msm_cam_media_controller *pmctl,
+ int msg_type, struct msm_free_buf *frame, int dirty)
+{
+ struct msm_cam_v4l2_dev_inst *pcam_inst;
+ int idx, rc = 0;
+
+ idx = msm_mctl_out_type_to_inst_index(
+ pmctl->sync.pcam_sync, msg_type);
+ pcam_inst = pmctl->sync.pcam_sync->dev_inst[idx];
+ D("%s:inst=0x%p, paddr=0x%x, dirty=%d",
+ __func__, pcam_inst, frame->paddr, dirty);
+ if (dirty)
+ /* the frame is dirty, not going to disptach to app */
+ rc = msm_mctl_release_free_buf(pmctl, msg_type, frame);
+ else
+ rc = msm_mctl_buf_done_proc(pmctl, pcam_inst,
+ msg_type, frame->paddr, NULL, 0);
+ return rc;
+}
+
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index a5d4b06..0bd42f7 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -190,12 +190,19 @@
};
struct msm_cam_evt_divert_frame {
- uint32_t image_mode;
- uint32_t op_mode;
+ unsigned short image_mode;
+ unsigned short op_mode;
unsigned short inst_idx;
unsigned short node_idx;
- unsigned int len;
- void *data;
+ unsigned long phy_addr;
+ uint32_t phy_offset;
+ uint32_t y_off;
+ uint32_t cbcr_off;
+ int32_t fd;
+ uint32_t frame_id;
+ int path;
+ uint32_t length;
+ struct timeval timestamp;
};
struct msm_isp_stats_event_ctrl {
@@ -203,7 +210,6 @@
union {
struct msm_cam_evt_msg isp_msg;
struct msm_ctrl_cmd ctrl;
- struct msm_cam_evt_divert_frame div_frame;
} isp_data;
};
@@ -465,6 +471,14 @@
int info_len;
};
+struct msm_mmap_entry {
+ uint32_t image_mode;/* extended mode */
+ uint32_t op_mode; /* operation mode, video, capture */
+ uint32_t vnode_idx; /* dev node idx */
+ uint32_t phy_addr; /* phy address: TBD: to be dropped */
+ uint32_t idx; /* v4l2 buffer index */
+};
+
#define MSM_MEM_MMAP 0
#define MSM_MEM_USERPTR 1
#define MSM_PLANE_MAX 8
@@ -595,8 +609,10 @@
#define MSM_V4L2_PID_SNOW_DETECTION (V4L2_CID_PRIVATE_BASE+12)
#define MSM_V4L2_PID_CTRL_CMD (V4L2_CID_PRIVATE_BASE+13)
#define MSM_V4L2_PID_EVT_SUB_INFO (V4L2_CID_PRIVATE_BASE+14)
-#define MSM_V4L2_PID_STROBE_FLASH (V4L2_CID_PRIVATE_BASE+15)
-#define MSM_V4L2_PID_MAX MSM_V4L2_PID_STROBE_FLASH
+#define MSM_V4L2_PID_STROBE_FLASH (V4L2_CID_PRIVATE_BASE+15)
+#define MSM_V4L2_PID_MMAP_ENTRY (V4L2_CID_PRIVATE_BASE+16)
+#define MSM_V4L2_PID_MMAP_INST (V4L2_CID_PRIVATE_BASE+17)
+#define MSM_V4L2_PID_MAX MSM_V4L2_PID_MMAP_INST
/* camera operation mode for video recording - two frame output queues */
#define MSM_V4L2_CAM_OP_DEFAULT 0