From 6e47c1eba7112dfcd5f7c07103a99e1e09a150bd Mon Sep 17 00:00:00 2001 From: Andrey Dolnikov Date: Thu, 17 Jan 2019 17:48:53 +0300 Subject: [PATCH 207/211] media: soc_camera: Add events support --- drivers/media/platform/soc_camera/rcar_isp.c | 2 +- drivers/media/platform/soc_camera/rcar_vin.c | 2 +- .../platform/soc_camera/sh_mobile_ceu_camera.c | 2 +- drivers/media/platform/soc_camera/soc_camera.c | 88 ++++++++++++++-------- include/media/soc_camera.h | 4 + 5 files changed, 65 insertions(+), 33 deletions(-) diff --git a/drivers/media/platform/soc_camera/rcar_isp.c b/drivers/media/platform/soc_camera/rcar_isp.c index 1127c7d..e7c2801 100644 --- a/drivers/media/platform/soc_camera/rcar_isp.c +++ b/drivers/media/platform/soc_camera/rcar_isp.c @@ -1549,7 +1549,7 @@ static int rcar_isp_try_fmt(struct soc_camera_device *icd, static unsigned int rcar_isp_poll(struct file *file, poll_table *pt) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); return vb2_poll(&icd->vb2_vidq, file, pt); } diff --git a/drivers/media/platform/soc_camera/rcar_vin.c b/drivers/media/platform/soc_camera/rcar_vin.c index bcc1cfd..9051590 100644 --- a/drivers/media/platform/soc_camera/rcar_vin.c +++ b/drivers/media/platform/soc_camera/rcar_vin.c @@ -2723,7 +2723,7 @@ static int rcar_vin_try_fmt(struct soc_camera_device *icd, static unsigned int rcar_vin_poll(struct file *file, poll_table *pt) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); return vb2_poll(&icd->vb2_vidq, file, pt); } diff --git a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c index 9180a1d..564d7e8 100644 --- a/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c +++ b/drivers/media/platform/soc_camera/sh_mobile_ceu_camera.c @@ -1560,7 +1560,7 @@ static int sh_mobile_ceu_set_liveselection(struct soc_camera_device *icd, static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); return vb2_poll(&icd->vb2_vidq, file, pt); } diff --git a/drivers/media/platform/soc_camera/soc_camera.c b/drivers/media/platform/soc_camera/soc_camera.c index cd2a135..7e5ca15 100644 --- a/drivers/media/platform/soc_camera/soc_camera.c +++ b/drivers/media/platform/soc_camera/soc_camera.c @@ -289,7 +289,7 @@ static int soc_camera_try_fmt(struct soc_camera_device *icd, static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); WARN_ON(priv != file->private_data); @@ -304,7 +304,7 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv, static int soc_camera_enum_input(struct file *file, void *priv, struct v4l2_input *inp) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); if (inp->index != 0) return -EINVAL; @@ -334,7 +334,7 @@ static int soc_camera_s_input(struct file *file, void *priv, unsigned int i) static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id a) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct v4l2_subdev *sd = soc_camera_to_subdev(icd); return v4l2_subdev_call(sd, video, s_std, a); @@ -342,7 +342,7 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id a) static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct v4l2_subdev *sd = soc_camera_to_subdev(icd); return v4l2_subdev_call(sd, video, g_std, a); @@ -351,7 +351,7 @@ static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a) static int soc_camera_enum_framesizes(struct file *file, void *fh, struct v4l2_frmsizeenum *fsize) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); return ici->ops->enum_framesizes(icd, fsize); @@ -361,7 +361,7 @@ static int soc_camera_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) { int ret; - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); WARN_ON(priv != file->private_data); @@ -377,7 +377,7 @@ static int soc_camera_reqbufs(struct file *file, void *priv, static int soc_camera_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); WARN_ON(priv != file->private_data); @@ -387,7 +387,7 @@ static int soc_camera_querybuf(struct file *file, void *priv, static int soc_camera_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); WARN_ON(priv != file->private_data); @@ -400,7 +400,7 @@ static int soc_camera_qbuf(struct file *file, void *priv, static int soc_camera_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); WARN_ON(priv != file->private_data); @@ -413,7 +413,7 @@ static int soc_camera_dqbuf(struct file *file, void *priv, static int soc_camera_create_bufs(struct file *file, void *priv, struct v4l2_create_buffers *create) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); int ret; if (icd->streamer && icd->streamer != file) @@ -428,7 +428,7 @@ static int soc_camera_create_bufs(struct file *file, void *priv, static int soc_camera_prepare_buf(struct file *file, void *priv, struct v4l2_buffer *b) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); return vb2_prepare_buf(&icd->vb2_vidq, b); } @@ -436,7 +436,7 @@ static int soc_camera_prepare_buf(struct file *file, void *priv, static int soc_camera_expbuf(struct file *file, void *priv, struct v4l2_exportbuffer *p) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); if (icd->streamer && icd->streamer != file) return -EBUSY; @@ -632,6 +632,7 @@ static int soc_camera_open(struct file *file) return -ENODEV; } + v4l2_fh_open(file); icd = video_get_drvdata(vdev); ici = to_soc_camera_host(icd->parent); @@ -708,7 +709,6 @@ static int soc_camera_open(struct file *file) } mutex_unlock(&ici->host_lock); - file->private_data = icd; dev_dbg(icd->pdev, "camera device open\n"); return 0; @@ -736,14 +736,19 @@ static int soc_camera_open(struct file *file) static int soc_camera_close(struct file *file) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + struct v4l2_event ev; mutex_lock(&ici->host_lock); if (icd->streamer == file) { if (ici->ops->init_videobuf2) vb2_queue_release(&icd->vb2_vidq); icd->streamer = NULL; + + memset(&ev, 0, sizeof(ev)); + ev.type = V4L2_EVENT_EOS; + v4l2_event_queue(icd->vdev, &ev); } icd->use_count--; if (!icd->use_count) { @@ -755,6 +760,8 @@ static int soc_camera_close(struct file *file) soc_camera_remove_device(icd); } + v4l2_fh_release(file); + mutex_unlock(&ici->host_lock); module_put(ici->ops->owner); @@ -767,7 +774,7 @@ static int soc_camera_close(struct file *file) static ssize_t soc_camera_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); dev_dbg(icd->pdev, "read called, buf %p\n", buf); @@ -783,7 +790,7 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf, static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); int err; @@ -807,12 +814,14 @@ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) static unsigned int soc_camera_poll(struct file *file, poll_table *pt) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); unsigned res = POLLERR; +/* if (icd->streamer != file) return POLLERR; +*/ mutex_lock(&ici->host_lock); res = ici->ops->poll(file, pt); @@ -833,7 +842,7 @@ static const struct v4l2_file_operations soc_camera_fops = { static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); int ret; WARN_ON(priv != file->private_data); @@ -862,7 +871,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv, static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fmtdesc *f) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); const struct soc_mbus_pixelfmt *format; WARN_ON(priv != file->private_data); @@ -881,7 +890,7 @@ static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv, static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct v4l2_pix_format *pix = &f->fmt.pix; WARN_ON(priv != file->private_data); @@ -904,7 +913,7 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv, static int soc_camera_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); WARN_ON(priv != file->private_data); @@ -916,8 +925,9 @@ static int soc_camera_querycap(struct file *file, void *priv, static int soc_camera_streamon(struct file *file, void *priv, enum v4l2_buf_type i) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct v4l2_event ev; int ret; WARN_ON(priv != file->private_data); @@ -933,14 +943,19 @@ static int soc_camera_streamon(struct file *file, void *priv, if (!ret) v4l2_subdev_call(sd, video, s_stream, 1); + memset(&ev, 0, sizeof(ev)); + ev.type = V4L2_EVENT_SOC_START_STREAM; + v4l2_event_queue(icd->vdev, &ev); + return ret; } static int soc_camera_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct v4l2_subdev *sd = soc_camera_to_subdev(icd); + struct v4l2_event ev; int ret; WARN_ON(priv != file->private_data); @@ -959,13 +974,17 @@ static int soc_camera_streamoff(struct file *file, void *priv, v4l2_subdev_call(sd, video, s_stream, 0); + memset(&ev, 0, sizeof(ev)); + ev.type = V4L2_EVENT_EOS; + v4l2_event_queue(icd->vdev, &ev); + return ret; } static int soc_camera_g_selection(struct file *file, void *fh, struct v4l2_selection *s) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); /* With a wrong type no need to try to fall back to cropping */ @@ -978,7 +997,7 @@ static int soc_camera_g_selection(struct file *file, void *fh, static int soc_camera_s_selection(struct file *file, void *fh, struct v4l2_selection *s) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); int ret; @@ -1023,7 +1042,7 @@ static int soc_camera_s_selection(struct file *file, void *fh, static int soc_camera_g_parm(struct file *file, void *fh, struct v4l2_streamparm *a) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); if (ici->ops->get_parm) @@ -1035,7 +1054,7 @@ static int soc_camera_g_parm(struct file *file, void *fh, static int soc_camera_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); if (ici->ops->set_parm) @@ -1047,7 +1066,7 @@ static int soc_camera_s_parm(struct file *file, void *fh, static int soc_camera_g_edid(struct file *file, void *fh, struct v4l2_edid *edid) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); if (ici->ops->get_edid) @@ -1060,7 +1079,7 @@ static int soc_camera_g_edid(struct file *file, void *fh, static int soc_camera_g_register(struct file *file, void *priv, struct v4l2_dbg_register *reg) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); if (ici->ops->get_register) @@ -1072,7 +1091,7 @@ static int soc_camera_g_register(struct file *file, void *priv, static int soc_camera_s_register(struct file *file, void *priv, const struct v4l2_dbg_register *reg) { - struct soc_camera_device *icd = file->private_data; + struct soc_camera_device *icd = video_drvdata(file); struct soc_camera_host *ici = to_soc_camera_host(icd->parent); if (ici->ops->set_register) @@ -2040,6 +2059,13 @@ static int soc_camera_device_register(struct soc_camera_device *icd) return 0; } +static int soc_camera_subscribe_event(struct v4l2_fh *fh, + const struct v4l2_event_subscription *sub) +{ + /* Just subscribe any event */ + return v4l2_event_subscribe(fh, sub, 16, NULL); +} + static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { .vidioc_querycap = soc_camera_querycap, .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap, @@ -2070,6 +2096,8 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { .vidioc_g_register = soc_camera_g_register, .vidioc_s_register = soc_camera_s_register, #endif + .vidioc_subscribe_event = soc_camera_subscribe_event, + .vidioc_unsubscribe_event = v4l2_event_unsubscribe, }; static int video_dev_create(struct soc_camera_device *icd) diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h index 2e44f96..53c650d 100644 --- a/include/media/soc_camera.h +++ b/include/media/soc_camera.h @@ -21,6 +21,10 @@ #include #include #include +#include + +#define V4L2_EVENT_SOC_START_STREAM (V4L2_EVENT_PRIVATE_START + 1) +#define V4L2_EVENT_SOC_PRIVATE_START (V4L2_EVENT_PRIVATE_START + 1) struct file; struct soc_camera_desc; -- 2.7.4