static int camera_v4l2_s_parm(struct file *filep, void *fh, struct v4l2_streamparm *parm) { int rc = 0; struct v4l2_event event; struct msm_v4l2_event_data *event_data = (struct msm_v4l2_event_data *)&event.u.data[0]; struct camera_v4l2_private *sp = fh_to_private(fh); camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_NEW_STREAM, -1, &event); rc = msm_create_stream(event_data->session_id, event_data->stream_id, &sp->vb2_q); if (rc < 0) return rc; rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT); if (rc < 0) goto error; rc = camera_check_event_status(&event); if (rc < 0) goto error; /* use stream_id as stream index */ parm->parm.capture.extendedmode = sp->stream_id; return rc; error: msm_delete_stream(event_data->session_id, event_data->stream_id); return rc; }
static int camera_v4l2_close(struct file *filep) { int rc = 0; /* */ int ret = 0; /* */ struct v4l2_event event; struct msm_video_device *pvdev = video_drvdata(filep); struct camera_v4l2_private *sp = fh_to_private(filep->private_data); // atomic_sub_return(1, &pvdev->opened); if (atomic_read(&pvdev->opened) == 0) { camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_DEL_STREAM, -1, &event); /* Donot wait, imaging server may have crashed */ /* */ ret = msm_post_event(&event, MSM_POST_EVT_TIMEOUT); if(ret < 0){ pr_err("%s:%d camera_v4l2_close_1 failed\n", __func__, __LINE__); } /* */ camera_pack_event(filep, MSM_CAMERA_DEL_SESSION, 0, -1, &event); /* Donot wait, imaging server may have crashed */ msm_post_event(&event, -1); msm_delete_command_ack_q(pvdev->vdev->num, 0); /* This should take care of both normal close * and application crashes */ msm_destroy_session(pvdev->vdev->num); pm_relax(&pvdev->vdev->dev); atomic_set(&pvdev->stream_cnt, 0); } else { camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_DEL_STREAM, -1, &event); /* Donot wait, imaging server may have crashed */ /* */ ret = msm_post_event(&event, MSM_POST_EVT_TIMEOUT); if(ret < 0){ pr_err("%s:%d camera_v4l2_close_2 failed\n", __func__, __LINE__); } /* */ msm_delete_command_ack_q(pvdev->vdev->num, sp->stream_id); msm_delete_stream(pvdev->vdev->num, sp->stream_id); } camera_v4l2_vb2_q_release(filep); camera_v4l2_fh_release(filep); return rc; }
static int camera_v4l2_vb2_q_init(struct file *filep) { struct camera_v4l2_private *sp = fh_to_private(filep->private_data); struct vb2_queue *q = &sp->vb2_q; memset(q, 0, sizeof(struct vb2_queue)); /* free up this buffer when stream is done */ q->drv_priv = kzalloc(sizeof(struct msm_v4l2_format_data), GFP_KERNEL); if (!q->drv_priv) { pr_err("%s : memory not available\n", __func__); return -ENOMEM; } q->mem_ops = msm_vb2_get_q_mem_ops(); q->ops = msm_vb2_get_q_ops(); /* default queue type */ q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->io_modes = VB2_USERPTR; q->io_flags = 0; q->buf_struct_size = sizeof(struct msm_vb2_buffer); vb2_queue_init(q); return 0; }
static int camera_v4l2_vb2_q_init(struct file *filep) { struct camera_v4l2_private *sp = fh_to_private(filep->private_data); struct vb2_queue *q = &sp->vb2_q; memset(q, 0, sizeof(struct vb2_queue)); q->drv_priv = kzalloc(sizeof(struct msm_v4l2_format_data), GFP_KERNEL); if (!q->drv_priv) { pr_err("%s : memory not available\n", __func__); return -ENOMEM; } q->mem_ops = msm_vb2_get_q_mem_ops(); q->ops = msm_vb2_get_q_ops(); q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; q->io_modes = VB2_USERPTR; q->io_flags = 0; q->buf_struct_size = sizeof(struct msm_vb2_buffer); q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; return vb2_queue_init(q); }
static int camera_v4l2_close(struct file *filep) { int rc = 0; struct v4l2_event event; struct msm_video_device *pvdev = video_drvdata(filep); struct camera_v4l2_private *sp = fh_to_private(filep->private_data); BUG_ON(!pvdev); atomic_sub_return(1, &pvdev->opened); if (atomic_read(&pvdev->opened) == 0) { if(1 == cam_wakelock_init && !wake_lock_active(&cam_wakelock)) { hw_camera_log_info("%s: start camera wake_lock_timeout!\n",__func__); //wake lock 500ms for camera exit wake_lock_timeout(&cam_wakelock, HZ/2); } else { hw_camera_log_info("%s: do not need wake_lock now, cam_wakelock_init = %d\n", __func__, cam_wakelock_init); } camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_DEL_STREAM, -1, &event); /* Donot wait, imaging server may have crashed */ msm_post_event(&event, MSM_POST_EVT_TIMEOUT); camera_pack_event(filep, MSM_CAMERA_DEL_SESSION, 0, -1, &event); /* Donot wait, imaging server may have crashed */ msm_post_event(&event, -1); msm_delete_command_ack_q(pvdev->vdev->num, 0); /* This should take care of both normal close * and application crashes */ msm_destroy_session(pvdev->vdev->num); pm_relax(&pvdev->vdev->dev); atomic_set(&pvdev->stream_cnt, 0); } else { camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_DEL_STREAM, -1, &event); /* Donot wait, imaging server may have crashed */ msm_post_event(&event, MSM_POST_EVT_TIMEOUT); msm_delete_command_ack_q(pvdev->vdev->num, sp->stream_id); msm_delete_stream(pvdev->vdev->num, sp->stream_id); } camera_v4l2_vb2_q_release(filep); camera_v4l2_fh_release(filep); return rc; }
static int camera_v4l2_unsubscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub) { int rc = 0; struct camera_v4l2_private *sp = fh_to_private(fh); rc = v4l2_event_unsubscribe(&sp->fh, sub); return rc; }
static int camera_v4l2_close(struct file *filep) { int rc = 0; struct v4l2_event event; struct msm_video_device *pvdev = video_drvdata(filep); struct camera_v4l2_private *sp = fh_to_private(filep->private_data); unsigned int opn_idx, mask; BUG_ON(!pvdev); opn_idx = atomic_read(&pvdev->opened); pr_debug("%s: close stream_id=%d\n", __func__, sp->stream_id); mask = (1 << sp->stream_id); opn_idx &= ~mask; atomic_set(&pvdev->opened, opn_idx); if (atomic_read(&pvdev->opened) == 0) { camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_DEL_STREAM, -1, &event); /* Donot wait, imaging server may have crashed */ msm_post_event(&event, MSM_POST_EVT_TIMEOUT); camera_pack_event(filep, MSM_CAMERA_DEL_SESSION, 0, -1, &event); /* Donot wait, imaging server may have crashed */ msm_post_event(&event, -1); msm_delete_command_ack_q(pvdev->vdev->num, 0); /* This should take care of both normal close * and application crashes */ msm_destroy_session(pvdev->vdev->num); /* Enable power collapse latency */ msm_pm_qos_update_request(CAMERA_ENABLE_PC_LATENCY); pm_relax(&pvdev->vdev->dev); } else { camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_DEL_STREAM, -1, &event); /* Donot wait, imaging server may have crashed */ msm_post_event(&event, MSM_POST_EVT_TIMEOUT); msm_delete_command_ack_q(pvdev->vdev->num, sp->stream_id); msm_delete_stream(pvdev->vdev->num, sp->stream_id); } camera_v4l2_vb2_q_release(filep); camera_v4l2_fh_release(filep); return rc; }
static int camera_v4l2_fh_release(struct file *filep) { struct camera_v4l2_private *sp = fh_to_private(filep->private_data); if (sp) { v4l2_fh_del(&sp->fh); v4l2_fh_exit(&sp->fh); } kzfree(sp); return 0; }
static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh, struct v4l2_format *pfmt) { int rc = 0; int i = 0; struct v4l2_event event; struct camera_v4l2_private *sp = fh_to_private(fh); struct msm_v4l2_format_data *user_fmt; if (pfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (WARN_ON(!sp->vb2_q.drv_priv)) return -ENOMEM; memcpy(sp->vb2_q.drv_priv, pfmt->fmt.raw_data, sizeof(struct msm_v4l2_format_data)); user_fmt = (struct msm_v4l2_format_data *)sp->vb2_q.drv_priv; pr_debug("%s: num planes :%c\n", __func__, user_fmt->num_planes); /*num_planes need to bound checked, otherwise for loop can execute forever */ if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES)) return -EINVAL; for (i = 0; i < user_fmt->num_planes; i++) pr_debug("%s: plane size[%d]\n", __func__, user_fmt->plane_sizes[i]); camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_S_FMT, -1, &event); rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT); /* */ if (rc < 0){ pr_err("%s:%d camera_v4l2_s_fmt_vid_cap_mplane failed\n", __func__, __LINE__); goto set_fmt_fail; } /* */ rc = camera_check_event_status(&event); if (rc < 0) goto set_fmt_fail; sp->is_vb2_valid = 1; } return rc; set_fmt_fail: kzfree(sp->vb2_q.drv_priv); sp->vb2_q.drv_priv = NULL; return rc; }
static int camera_v4l2_close(struct file *filep) { int rc = 0; struct v4l2_event event; struct msm_video_device *pvdev = video_drvdata(filep); struct camera_v4l2_private *sp = fh_to_private(filep->private_data); BUG_ON(!pvdev); atomic_sub_return(1, &pvdev->opened); if (atomic_read(&pvdev->opened) == 0) { camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_DEL_STREAM, -1, &event); /* Donot wait, imaging server may have crashed */ msm_post_event(&event, MSM_POST_EVT_TIMEOUT); camera_pack_event(filep, MSM_CAMERA_DEL_SESSION, 0, -1, &event); /* Donot wait, imaging server may have crashed */ #if 1 // wait for signal msm_post_event(&event, MSM_POST_EVT_TIMEOUT); #else msm_post_event(&event, -1); #endif msm_delete_command_ack_q(pvdev->vdev->num, 0); /* This should take care of both normal close * and application crashes */ msm_destroy_session(pvdev->vdev->num); } else { camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_DEL_STREAM, -1, &event); /* Donot wait, imaging server may have crashed */ msm_post_event(&event, MSM_POST_EVT_TIMEOUT); msm_delete_command_ack_q(pvdev->vdev->num, sp->stream_id); msm_delete_stream(pvdev->vdev->num, sp->stream_id); } camera_v4l2_vb2_q_release(filep); camera_v4l2_fh_release(filep); return rc; }
static unsigned int camera_v4l2_poll(struct file *filep, struct poll_table_struct *wait) { int rc = 0; struct camera_v4l2_private *sp = fh_to_private(filep->private_data); if (sp->is_vb2_valid == 1) rc = vb2_poll(&sp->vb2_q, filep, wait); poll_wait(filep, &sp->fh.wait, wait); if (v4l2_event_pending(&sp->fh)) rc |= POLLPRI; return rc; }
static int camera_v4l2_dqbuf(struct file *filep, void *fh, struct v4l2_buffer *pb) { int ret; struct msm_session *session; struct camera_v4l2_private *sp = fh_to_private(fh); struct msm_video_device *pvdev = video_drvdata(filep); unsigned int session_id = pvdev->vdev->num; session = msm_session_find(session_id); if (WARN_ON(!session)) return -EIO; mutex_lock(&session->lock); ret = vb2_dqbuf(&sp->vb2_q, pb, filep->f_flags & O_NONBLOCK); mutex_unlock(&session->lock); return ret; }
static void camera_pack_event(struct file *filep, int evt_id, int command, int value, struct v4l2_event *event) { struct msm_v4l2_event_data *event_data = (struct msm_v4l2_event_data *)&event->u.data[0]; struct msm_video_device *pvdev = video_drvdata(filep); struct camera_v4l2_private *sp = fh_to_private(filep->private_data); /* always MSM_CAMERA_V4L2_EVENT_TYPE */ event->type = MSM_CAMERA_V4L2_EVENT_TYPE; event->id = evt_id; event_data->command = command; event_data->session_id = pvdev->vdev->num; event_data->stream_id = sp->stream_id; event_data->arg_value = value; }
static int camera_v4l2_reqbufs(struct file *filep, void *fh, struct v4l2_requestbuffers *req) { int ret; struct msm_session *session; struct camera_v4l2_private *sp = fh_to_private(fh); struct msm_video_device *pvdev = video_drvdata(filep); unsigned int session_id = pvdev->vdev->num; session = msm_session_find(session_id); if (WARN_ON(!session)) return -EIO; mutex_lock(&session->lock); ret = vb2_reqbufs(&sp->vb2_q, req); mutex_unlock(&session->lock); return ret; }
static int camera_v4l2_streamoff(struct file *filep, void *fh, enum v4l2_buf_type buf_type) { struct v4l2_event event; int rc; struct camera_v4l2_private *sp = fh_to_private(fh); camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_STREAM_OFF, -1, &event); rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT); if (rc < 0) return rc; rc = camera_check_event_status(&event); vb2_streamoff(&sp->vb2_q, buf_type); return rc; }
static int camera_v4l2_streamon(struct file *filep, void *fh, enum v4l2_buf_type buf_type) { struct v4l2_event event; int rc; struct camera_v4l2_private *sp = fh_to_private(fh); rc = vb2_streamon(&sp->vb2_q, buf_type); camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_STREAM_ON, -1, &event); rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT); if (rc < 0) { pr_err("%s : msm_post_event failed!", __FUNCTION__); return rc; } rc = camera_check_event_status(&event); return rc; }
static int camera_v4l2_close(struct file *filep) { int rc = 0; struct v4l2_event event; struct msm_video_device *pvdev = video_drvdata(filep); struct camera_v4l2_private *sp = fh_to_private(filep->private_data); unsigned int opn_idx, mask; struct msm_session *session; BUG_ON(!pvdev); session = msm_session_find(pvdev->vdev->num); if (WARN_ON(!session)) return -EIO; opn_idx = atomic_read(&pvdev->opened); pr_info("[CAM]%s: close stream_id=%d +\n", __func__, sp->stream_id); pr_debug("%s: close stream_id=%d\n", __func__, sp->stream_id); mask = (1 << sp->stream_id); opn_idx &= ~mask; atomic_set(&pvdev->opened, opn_idx); if (atomic_read(&pvdev->opened) == 0) { mutex_lock(&session->close_lock); camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_DEL_STREAM, -1, &event); pr_info("[CAM]%s: + MSM_CAMERA_PRIV_DEL_STREAM 1\n", __func__); msm_post_event(&event, MSM_POST_EVT_TIMEOUT); pr_info("[CAM]%s: -\n", __func__); camera_pack_event(filep, MSM_CAMERA_DEL_SESSION, 0, -1, &event); pr_info("[CAM]%s: + MSM_CAMERA_DEL_SESSION 2\n", __func__); msm_post_event(&event, MSM_POST_EVT_TIMEOUT); pr_info("[CAM]%s: -\n", __func__); msm_delete_command_ack_q(pvdev->vdev->num, 0); mutex_unlock(&session->close_lock); pr_info("[CAM]%s: msm_delete_command_ack_q done\n", __func__); camera_v4l2_vb2_q_release(filep); pr_info("[CAM]%s: camera_v4l2_vb2_q_release done\n", __func__); msm_destroy_session(pvdev->vdev->num); pr_info("[CAM]%s: msm_destroy_session done\n", __func__); pm_relax(&pvdev->vdev->dev); pr_info("[CAM]%s: pm_relax done\n", __func__); } else { mutex_lock(&session->close_lock); camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_DEL_STREAM, -1, &event); pr_info("[CAM]%s: + MSM_CAMERA_PRIV_DEL_STREAM\n", __func__); msm_post_event(&event, MSM_POST_EVT_TIMEOUT); pr_info("[CAM]%s: -\n", __func__); msm_delete_command_ack_q(pvdev->vdev->num, sp->stream_id); camera_v4l2_vb2_q_release(filep); msm_delete_stream(pvdev->vdev->num, sp->stream_id); mutex_unlock(&session->close_lock); } camera_v4l2_fh_release(filep); pr_info("[CAM]%s: close -\n", __func__); return rc; }