Loading drivers/media/video/cpia2/cpia2_v4l.c +126 −247 Original line number Diff line number Diff line Loading @@ -395,10 +395,14 @@ static int sync(struct camera_data *cam, int frame_nr) * *****************************************************************************/ static int ioctl_set_gpio(void *arg, struct camera_data *cam) static long cpia2_default(struct file *file, void *fh, int cmd, void *arg) { struct camera_data *cam = video_drvdata(file); __u32 gpio_val; if (cmd != CPIA2_CID_GPIO) return -EINVAL; gpio_val = *(__u32*) arg; if (gpio_val &~ 0xFFU) Loading @@ -415,11 +419,10 @@ static int ioctl_set_gpio(void *arg, struct camera_data *cam) * *****************************************************************************/ static int ioctl_querycap(void *arg, struct camera_data *cam) static int cpia2_querycap(struct file *file, void *fh, struct v4l2_capability *vc) { struct v4l2_capability *vc = arg; struct camera_data *cam = video_drvdata(file); memset(vc, 0, sizeof(*vc)); strcpy(vc->driver, "cpia2"); if (cam->params.pnp_id.product == 0x151) Loading Loading @@ -479,22 +482,26 @@ static int ioctl_querycap(void *arg, struct camera_data *cam) * *****************************************************************************/ static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam) static int cpia2_enum_input(struct file *file, void *fh, struct v4l2_input *i) { struct v4l2_input *i = arg; if(ioclt_nr != VIDIOC_G_INPUT) { if (i->index != 0) if (i->index) return -EINVAL; } memset(i, 0, sizeof(*i)); strcpy(i->name, "Camera"); i->type = V4L2_INPUT_TYPE_CAMERA; return 0; } static int cpia2_g_input(struct file *file, void *fh, unsigned int *i) { *i = 0; return 0; } static int cpia2_s_input(struct file *file, void *fh, unsigned int i) { return i ? -EINVAL : 0; } /****************************************************************************** * * ioctl_enum_fmt Loading @@ -503,9 +510,9 @@ static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_enum_fmt(void *arg,struct camera_data *cam) static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) { struct v4l2_fmtdesc *f = arg; int index = f->index; if (index < 0 || index > 1) Loading Loading @@ -539,12 +546,10 @@ static int ioctl_enum_fmt(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_try_fmt(void *arg,struct camera_data *cam) static int cpia2_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { struct v4l2_format *f = arg; if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; struct camera_data *cam = video_drvdata(file); if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG && f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) Loading Loading @@ -603,12 +608,17 @@ static int ioctl_try_fmt(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh) static int cpia2_s_fmt_vid_cap(struct file *file, void *_fh, struct v4l2_format *f) { struct v4l2_format *f = arg; struct camera_data *cam = video_drvdata(file); struct cpia2_fh *fh = _fh; int err, frame; err = ioctl_try_fmt(arg, cam); err = v4l2_prio_check(&cam->prio, fh->prio); if (err) return err; err = cpia2_try_fmt_vid_cap(file, _fh, f); if(err != 0) return err; Loading Loading @@ -658,12 +668,10 @@ static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh) * *****************************************************************************/ static int ioctl_get_fmt(void *arg,struct camera_data *cam) static int cpia2_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { struct v4l2_format *f = arg; if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; struct camera_data *cam = video_drvdata(file); f->fmt.pix.width = cam->width; f->fmt.pix.height = cam->height; Loading @@ -686,9 +694,9 @@ static int ioctl_get_fmt(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_cropcap(void *arg,struct camera_data *cam) static int cpia2_cropcap(struct file *file, void *fh, struct v4l2_cropcap *c) { struct v4l2_cropcap *c = arg; struct camera_data *cam = video_drvdata(file); if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; Loading @@ -715,9 +723,9 @@ static int ioctl_cropcap(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_queryctrl(void *arg,struct camera_data *cam) static int cpia2_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) { struct v4l2_queryctrl *c = arg; struct camera_data *cam = video_drvdata(file); int i; for(i=0; i<NUM_CONTROLS; ++i) { Loading Loading @@ -783,12 +791,9 @@ static int ioctl_queryctrl(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_querymenu(void *arg,struct camera_data *cam) static int cpia2_querymenu(struct file *file, void *fh, struct v4l2_querymenu *m) { struct v4l2_querymenu *m = arg; memset(m->name, 0, sizeof(m->name)); m->reserved = 0; struct camera_data *cam = video_drvdata(file); switch(m->id) { case CPIA2_CID_FLICKER_MODE: Loading Loading @@ -837,9 +842,9 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_g_ctrl(void *arg,struct camera_data *cam) static int cpia2_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) { struct v4l2_control *c = arg; struct camera_data *cam = video_drvdata(file); switch(c->id) { case V4L2_CID_BRIGHTNESS: Loading Loading @@ -955,9 +960,9 @@ static int ioctl_g_ctrl(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_s_ctrl(void *arg,struct camera_data *cam) static int cpia2_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) { struct v4l2_control *c = arg; struct camera_data *cam = video_drvdata(file); int i; int retval = 0; Loading Loading @@ -1031,9 +1036,9 @@ static int ioctl_s_ctrl(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam) static int cpia2_g_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms) { struct v4l2_jpegcompression *parms = arg; struct camera_data *cam = video_drvdata(file); memset(parms, 0, sizeof(*parms)); Loading Loading @@ -1072,9 +1077,9 @@ static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam) static int cpia2_s_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms) { struct v4l2_jpegcompression *parms = arg; struct camera_data *cam = video_drvdata(file); DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n", parms->APP_len, parms->COM_len); Loading Loading @@ -1121,9 +1126,9 @@ static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_reqbufs(void *arg,struct camera_data *cam) static int cpia2_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *req) { struct v4l2_requestbuffers *req = arg; struct camera_data *cam = video_drvdata(file); if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || req->memory != V4L2_MEMORY_MMAP) Loading @@ -1144,9 +1149,9 @@ static int ioctl_reqbufs(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_querybuf(void *arg,struct camera_data *cam) static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_buffer *buf = arg; struct camera_data *cam = video_drvdata(file); if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || buf->index > cam->num_frames) Loading Loading @@ -1192,9 +1197,9 @@ static int ioctl_querybuf(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_qbuf(void *arg,struct camera_data *cam) static int cpia2_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_buffer *buf = arg; struct camera_data *cam = video_drvdata(file); if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || buf->memory != V4L2_MEMORY_MMAP || Loading Loading @@ -1248,9 +1253,9 @@ static int find_earliest_filled_buffer(struct camera_data *cam) * *****************************************************************************/ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file) static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_buffer *buf = arg; struct camera_data *cam = video_drvdata(file); int frame; if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || Loading Loading @@ -1296,210 +1301,56 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file) return 0; } /****************************************************************************** * * cpia2_ioctl * *****************************************************************************/ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) static int cpia2_g_priority(struct file *file, void *_fh, enum v4l2_priority *p) { struct camera_data *cam = video_drvdata(file); long retval = 0; struct cpia2_fh *fh = _fh; if (!cam) return -ENOTTY; if (!cam->present) return -ENODEV; /* Priority check */ switch (cmd) { case VIDIOC_S_FMT: { struct cpia2_fh *fh = file->private_data; retval = v4l2_prio_check(&cam->prio, fh->prio); if (retval) return retval; break; } default: break; *p = fh->prio; return 0; } switch (cmd) { /* CPIA2 extension to Video4Linux API */ case CPIA2_IOC_SET_GPIO: retval = ioctl_set_gpio(arg, cam); break; case VIDIOC_QUERYCAP: retval = ioctl_querycap(arg,cam); break; case VIDIOC_ENUMINPUT: case VIDIOC_G_INPUT: case VIDIOC_S_INPUT: retval = ioctl_input(cmd, arg, cam); break; case VIDIOC_ENUM_FMT: retval = ioctl_enum_fmt(arg,cam); break; case VIDIOC_TRY_FMT: retval = ioctl_try_fmt(arg,cam); break; case VIDIOC_G_FMT: retval = ioctl_get_fmt(arg,cam); break; case VIDIOC_S_FMT: retval = ioctl_set_fmt(arg,cam,file->private_data); break; case VIDIOC_CROPCAP: retval = ioctl_cropcap(arg,cam); break; case VIDIOC_G_CROP: case VIDIOC_S_CROP: // TODO: I think cropping can be implemented - SJB retval = -EINVAL; break; case VIDIOC_QUERYCTRL: retval = ioctl_queryctrl(arg,cam); break; case VIDIOC_QUERYMENU: retval = ioctl_querymenu(arg,cam); break; case VIDIOC_G_CTRL: retval = ioctl_g_ctrl(arg,cam); break; case VIDIOC_S_CTRL: retval = ioctl_s_ctrl(arg,cam); break; case VIDIOC_G_JPEGCOMP: retval = ioctl_g_jpegcomp(arg,cam); break; case VIDIOC_S_JPEGCOMP: retval = ioctl_s_jpegcomp(arg,cam); break; case VIDIOC_G_PRIORITY: static int cpia2_s_priority(struct file *file, void *_fh, enum v4l2_priority prio) { struct cpia2_fh *fh = file->private_data; *(enum v4l2_priority*)arg = fh->prio; break; } case VIDIOC_S_PRIORITY: { struct cpia2_fh *fh = file->private_data; enum v4l2_priority prio; prio = *(enum v4l2_priority*)arg; if(cam->streaming && prio != fh->prio && fh->prio == V4L2_PRIORITY_RECORD) { struct camera_data *cam = video_drvdata(file); struct cpia2_fh *fh = fh; if (cam->streaming && prio != fh->prio && fh->prio == V4L2_PRIORITY_RECORD) /* Can't drop record priority while streaming */ retval = -EBUSY; } else if(prio == V4L2_PRIORITY_RECORD && prio != fh->prio && v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD) { return -EBUSY; if (prio == V4L2_PRIORITY_RECORD && prio != fh->prio && v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD) /* Only one program can record at a time */ retval = -EBUSY; } else { retval = v4l2_prio_change(&cam->prio, &fh->prio, prio); } break; return -EBUSY; return v4l2_prio_change(&cam->prio, &fh->prio, prio); } case VIDIOC_REQBUFS: retval = ioctl_reqbufs(arg,cam); break; case VIDIOC_QUERYBUF: retval = ioctl_querybuf(arg,cam); break; case VIDIOC_QBUF: retval = ioctl_qbuf(arg,cam); break; case VIDIOC_DQBUF: retval = ioctl_dqbuf(arg,cam,file); break; case VIDIOC_STREAMON: static int cpia2_streamon(struct file *file, void *fh, enum v4l2_buf_type type) { int type; struct camera_data *cam = video_drvdata(file); DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming); type = *(int*)arg; if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) retval = -EINVAL; return -EINVAL; if(!cam->streaming) { retval = cpia2_usb_stream_start(cam, if (!cam->streaming) return cpia2_usb_stream_start(cam, cam->params.camera_state.stream_mode); } else { retval = -EINVAL; return -EINVAL; } break; } case VIDIOC_STREAMOFF: static int cpia2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) { int type; struct camera_data *cam = video_drvdata(file); DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming); type = *(int*)arg; if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) retval = -EINVAL; if(cam->streaming) { retval = cpia2_usb_stream_stop(cam); } else { retval = -EINVAL; } break; } case VIDIOC_ENUMOUTPUT: case VIDIOC_G_OUTPUT: case VIDIOC_S_OUTPUT: case VIDIOC_G_MODULATOR: case VIDIOC_S_MODULATOR: case VIDIOC_ENUMAUDIO: case VIDIOC_G_AUDIO: case VIDIOC_S_AUDIO: case VIDIOC_ENUMAUDOUT: case VIDIOC_G_AUDOUT: case VIDIOC_S_AUDOUT: case VIDIOC_ENUMSTD: case VIDIOC_QUERYSTD: case VIDIOC_G_STD: case VIDIOC_S_STD: case VIDIOC_G_TUNER: case VIDIOC_S_TUNER: case VIDIOC_G_FREQUENCY: case VIDIOC_S_FREQUENCY: case VIDIOC_OVERLAY: case VIDIOC_G_FBUF: case VIDIOC_S_FBUF: case VIDIOC_G_PARM: case VIDIOC_S_PARM: retval = -EINVAL; break; default: retval = -ENOIOCTLCMD; break; } return retval; } return -EINVAL; static long cpia2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, cpia2_do_ioctl); if (cam->streaming) return cpia2_usb_stream_stop(cam); return -EINVAL; } /****************************************************************************** Loading Loading @@ -1550,6 +1401,33 @@ static void reset_camera_struct_v4l(struct camera_data *cam) v4l2_prio_init(&cam->prio); } static const struct v4l2_ioctl_ops cpia2_ioctl_ops = { .vidioc_querycap = cpia2_querycap, .vidioc_enum_input = cpia2_enum_input, .vidioc_g_input = cpia2_g_input, .vidioc_s_input = cpia2_s_input, .vidioc_enum_fmt_vid_cap = cpia2_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = cpia2_g_fmt_vid_cap, .vidioc_s_fmt_vid_cap = cpia2_s_fmt_vid_cap, .vidioc_try_fmt_vid_cap = cpia2_try_fmt_vid_cap, .vidioc_queryctrl = cpia2_queryctrl, .vidioc_querymenu = cpia2_querymenu, .vidioc_g_ctrl = cpia2_g_ctrl, .vidioc_s_ctrl = cpia2_s_ctrl, .vidioc_g_jpegcomp = cpia2_g_jpegcomp, .vidioc_s_jpegcomp = cpia2_s_jpegcomp, .vidioc_cropcap = cpia2_cropcap, .vidioc_reqbufs = cpia2_reqbufs, .vidioc_querybuf = cpia2_querybuf, .vidioc_qbuf = cpia2_qbuf, .vidioc_dqbuf = cpia2_dqbuf, .vidioc_streamon = cpia2_streamon, .vidioc_streamoff = cpia2_streamoff, .vidioc_g_priority = cpia2_g_priority, .vidioc_s_priority = cpia2_s_priority, .vidioc_default = cpia2_default, }; /*** * The v4l video device structure initialized for this device ***/ Loading @@ -1559,7 +1437,7 @@ static const struct v4l2_file_operations cpia2_fops = { .release = cpia2_close, .read = cpia2_v4l_read, .poll = cpia2_v4l_poll, .unlocked_ioctl = cpia2_ioctl, .unlocked_ioctl = video_ioctl2, .mmap = cpia2_mmap, }; Loading @@ -1567,6 +1445,7 @@ static struct video_device cpia2_template = { /* I could not find any place for the old .initialize initializer?? */ .name = "CPiA2 Camera", .fops = &cpia2_fops, .ioctl_ops = &cpia2_ioctl_ops, .release = video_device_release, }; Loading Loading
drivers/media/video/cpia2/cpia2_v4l.c +126 −247 Original line number Diff line number Diff line Loading @@ -395,10 +395,14 @@ static int sync(struct camera_data *cam, int frame_nr) * *****************************************************************************/ static int ioctl_set_gpio(void *arg, struct camera_data *cam) static long cpia2_default(struct file *file, void *fh, int cmd, void *arg) { struct camera_data *cam = video_drvdata(file); __u32 gpio_val; if (cmd != CPIA2_CID_GPIO) return -EINVAL; gpio_val = *(__u32*) arg; if (gpio_val &~ 0xFFU) Loading @@ -415,11 +419,10 @@ static int ioctl_set_gpio(void *arg, struct camera_data *cam) * *****************************************************************************/ static int ioctl_querycap(void *arg, struct camera_data *cam) static int cpia2_querycap(struct file *file, void *fh, struct v4l2_capability *vc) { struct v4l2_capability *vc = arg; struct camera_data *cam = video_drvdata(file); memset(vc, 0, sizeof(*vc)); strcpy(vc->driver, "cpia2"); if (cam->params.pnp_id.product == 0x151) Loading Loading @@ -479,22 +482,26 @@ static int ioctl_querycap(void *arg, struct camera_data *cam) * *****************************************************************************/ static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam) static int cpia2_enum_input(struct file *file, void *fh, struct v4l2_input *i) { struct v4l2_input *i = arg; if(ioclt_nr != VIDIOC_G_INPUT) { if (i->index != 0) if (i->index) return -EINVAL; } memset(i, 0, sizeof(*i)); strcpy(i->name, "Camera"); i->type = V4L2_INPUT_TYPE_CAMERA; return 0; } static int cpia2_g_input(struct file *file, void *fh, unsigned int *i) { *i = 0; return 0; } static int cpia2_s_input(struct file *file, void *fh, unsigned int i) { return i ? -EINVAL : 0; } /****************************************************************************** * * ioctl_enum_fmt Loading @@ -503,9 +510,9 @@ static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_enum_fmt(void *arg,struct camera_data *cam) static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f) { struct v4l2_fmtdesc *f = arg; int index = f->index; if (index < 0 || index > 1) Loading Loading @@ -539,12 +546,10 @@ static int ioctl_enum_fmt(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_try_fmt(void *arg,struct camera_data *cam) static int cpia2_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { struct v4l2_format *f = arg; if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; struct camera_data *cam = video_drvdata(file); if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG && f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) Loading Loading @@ -603,12 +608,17 @@ static int ioctl_try_fmt(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh) static int cpia2_s_fmt_vid_cap(struct file *file, void *_fh, struct v4l2_format *f) { struct v4l2_format *f = arg; struct camera_data *cam = video_drvdata(file); struct cpia2_fh *fh = _fh; int err, frame; err = ioctl_try_fmt(arg, cam); err = v4l2_prio_check(&cam->prio, fh->prio); if (err) return err; err = cpia2_try_fmt_vid_cap(file, _fh, f); if(err != 0) return err; Loading Loading @@ -658,12 +668,10 @@ static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh) * *****************************************************************************/ static int ioctl_get_fmt(void *arg,struct camera_data *cam) static int cpia2_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) { struct v4l2_format *f = arg; if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; struct camera_data *cam = video_drvdata(file); f->fmt.pix.width = cam->width; f->fmt.pix.height = cam->height; Loading @@ -686,9 +694,9 @@ static int ioctl_get_fmt(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_cropcap(void *arg,struct camera_data *cam) static int cpia2_cropcap(struct file *file, void *fh, struct v4l2_cropcap *c) { struct v4l2_cropcap *c = arg; struct camera_data *cam = video_drvdata(file); if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; Loading @@ -715,9 +723,9 @@ static int ioctl_cropcap(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_queryctrl(void *arg,struct camera_data *cam) static int cpia2_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) { struct v4l2_queryctrl *c = arg; struct camera_data *cam = video_drvdata(file); int i; for(i=0; i<NUM_CONTROLS; ++i) { Loading Loading @@ -783,12 +791,9 @@ static int ioctl_queryctrl(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_querymenu(void *arg,struct camera_data *cam) static int cpia2_querymenu(struct file *file, void *fh, struct v4l2_querymenu *m) { struct v4l2_querymenu *m = arg; memset(m->name, 0, sizeof(m->name)); m->reserved = 0; struct camera_data *cam = video_drvdata(file); switch(m->id) { case CPIA2_CID_FLICKER_MODE: Loading Loading @@ -837,9 +842,9 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_g_ctrl(void *arg,struct camera_data *cam) static int cpia2_g_ctrl(struct file *file, void *fh, struct v4l2_control *c) { struct v4l2_control *c = arg; struct camera_data *cam = video_drvdata(file); switch(c->id) { case V4L2_CID_BRIGHTNESS: Loading Loading @@ -955,9 +960,9 @@ static int ioctl_g_ctrl(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_s_ctrl(void *arg,struct camera_data *cam) static int cpia2_s_ctrl(struct file *file, void *fh, struct v4l2_control *c) { struct v4l2_control *c = arg; struct camera_data *cam = video_drvdata(file); int i; int retval = 0; Loading Loading @@ -1031,9 +1036,9 @@ static int ioctl_s_ctrl(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam) static int cpia2_g_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms) { struct v4l2_jpegcompression *parms = arg; struct camera_data *cam = video_drvdata(file); memset(parms, 0, sizeof(*parms)); Loading Loading @@ -1072,9 +1077,9 @@ static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam) static int cpia2_s_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms) { struct v4l2_jpegcompression *parms = arg; struct camera_data *cam = video_drvdata(file); DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n", parms->APP_len, parms->COM_len); Loading Loading @@ -1121,9 +1126,9 @@ static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_reqbufs(void *arg,struct camera_data *cam) static int cpia2_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *req) { struct v4l2_requestbuffers *req = arg; struct camera_data *cam = video_drvdata(file); if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || req->memory != V4L2_MEMORY_MMAP) Loading @@ -1144,9 +1149,9 @@ static int ioctl_reqbufs(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_querybuf(void *arg,struct camera_data *cam) static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_buffer *buf = arg; struct camera_data *cam = video_drvdata(file); if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || buf->index > cam->num_frames) Loading Loading @@ -1192,9 +1197,9 @@ static int ioctl_querybuf(void *arg,struct camera_data *cam) * *****************************************************************************/ static int ioctl_qbuf(void *arg,struct camera_data *cam) static int cpia2_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_buffer *buf = arg; struct camera_data *cam = video_drvdata(file); if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || buf->memory != V4L2_MEMORY_MMAP || Loading Loading @@ -1248,9 +1253,9 @@ static int find_earliest_filled_buffer(struct camera_data *cam) * *****************************************************************************/ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file) static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) { struct v4l2_buffer *buf = arg; struct camera_data *cam = video_drvdata(file); int frame; if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || Loading Loading @@ -1296,210 +1301,56 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file) return 0; } /****************************************************************************** * * cpia2_ioctl * *****************************************************************************/ static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg) static int cpia2_g_priority(struct file *file, void *_fh, enum v4l2_priority *p) { struct camera_data *cam = video_drvdata(file); long retval = 0; struct cpia2_fh *fh = _fh; if (!cam) return -ENOTTY; if (!cam->present) return -ENODEV; /* Priority check */ switch (cmd) { case VIDIOC_S_FMT: { struct cpia2_fh *fh = file->private_data; retval = v4l2_prio_check(&cam->prio, fh->prio); if (retval) return retval; break; } default: break; *p = fh->prio; return 0; } switch (cmd) { /* CPIA2 extension to Video4Linux API */ case CPIA2_IOC_SET_GPIO: retval = ioctl_set_gpio(arg, cam); break; case VIDIOC_QUERYCAP: retval = ioctl_querycap(arg,cam); break; case VIDIOC_ENUMINPUT: case VIDIOC_G_INPUT: case VIDIOC_S_INPUT: retval = ioctl_input(cmd, arg, cam); break; case VIDIOC_ENUM_FMT: retval = ioctl_enum_fmt(arg,cam); break; case VIDIOC_TRY_FMT: retval = ioctl_try_fmt(arg,cam); break; case VIDIOC_G_FMT: retval = ioctl_get_fmt(arg,cam); break; case VIDIOC_S_FMT: retval = ioctl_set_fmt(arg,cam,file->private_data); break; case VIDIOC_CROPCAP: retval = ioctl_cropcap(arg,cam); break; case VIDIOC_G_CROP: case VIDIOC_S_CROP: // TODO: I think cropping can be implemented - SJB retval = -EINVAL; break; case VIDIOC_QUERYCTRL: retval = ioctl_queryctrl(arg,cam); break; case VIDIOC_QUERYMENU: retval = ioctl_querymenu(arg,cam); break; case VIDIOC_G_CTRL: retval = ioctl_g_ctrl(arg,cam); break; case VIDIOC_S_CTRL: retval = ioctl_s_ctrl(arg,cam); break; case VIDIOC_G_JPEGCOMP: retval = ioctl_g_jpegcomp(arg,cam); break; case VIDIOC_S_JPEGCOMP: retval = ioctl_s_jpegcomp(arg,cam); break; case VIDIOC_G_PRIORITY: static int cpia2_s_priority(struct file *file, void *_fh, enum v4l2_priority prio) { struct cpia2_fh *fh = file->private_data; *(enum v4l2_priority*)arg = fh->prio; break; } case VIDIOC_S_PRIORITY: { struct cpia2_fh *fh = file->private_data; enum v4l2_priority prio; prio = *(enum v4l2_priority*)arg; if(cam->streaming && prio != fh->prio && fh->prio == V4L2_PRIORITY_RECORD) { struct camera_data *cam = video_drvdata(file); struct cpia2_fh *fh = fh; if (cam->streaming && prio != fh->prio && fh->prio == V4L2_PRIORITY_RECORD) /* Can't drop record priority while streaming */ retval = -EBUSY; } else if(prio == V4L2_PRIORITY_RECORD && prio != fh->prio && v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD) { return -EBUSY; if (prio == V4L2_PRIORITY_RECORD && prio != fh->prio && v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD) /* Only one program can record at a time */ retval = -EBUSY; } else { retval = v4l2_prio_change(&cam->prio, &fh->prio, prio); } break; return -EBUSY; return v4l2_prio_change(&cam->prio, &fh->prio, prio); } case VIDIOC_REQBUFS: retval = ioctl_reqbufs(arg,cam); break; case VIDIOC_QUERYBUF: retval = ioctl_querybuf(arg,cam); break; case VIDIOC_QBUF: retval = ioctl_qbuf(arg,cam); break; case VIDIOC_DQBUF: retval = ioctl_dqbuf(arg,cam,file); break; case VIDIOC_STREAMON: static int cpia2_streamon(struct file *file, void *fh, enum v4l2_buf_type type) { int type; struct camera_data *cam = video_drvdata(file); DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming); type = *(int*)arg; if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) retval = -EINVAL; return -EINVAL; if(!cam->streaming) { retval = cpia2_usb_stream_start(cam, if (!cam->streaming) return cpia2_usb_stream_start(cam, cam->params.camera_state.stream_mode); } else { retval = -EINVAL; return -EINVAL; } break; } case VIDIOC_STREAMOFF: static int cpia2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) { int type; struct camera_data *cam = video_drvdata(file); DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming); type = *(int*)arg; if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE) retval = -EINVAL; if(cam->streaming) { retval = cpia2_usb_stream_stop(cam); } else { retval = -EINVAL; } break; } case VIDIOC_ENUMOUTPUT: case VIDIOC_G_OUTPUT: case VIDIOC_S_OUTPUT: case VIDIOC_G_MODULATOR: case VIDIOC_S_MODULATOR: case VIDIOC_ENUMAUDIO: case VIDIOC_G_AUDIO: case VIDIOC_S_AUDIO: case VIDIOC_ENUMAUDOUT: case VIDIOC_G_AUDOUT: case VIDIOC_S_AUDOUT: case VIDIOC_ENUMSTD: case VIDIOC_QUERYSTD: case VIDIOC_G_STD: case VIDIOC_S_STD: case VIDIOC_G_TUNER: case VIDIOC_S_TUNER: case VIDIOC_G_FREQUENCY: case VIDIOC_S_FREQUENCY: case VIDIOC_OVERLAY: case VIDIOC_G_FBUF: case VIDIOC_S_FBUF: case VIDIOC_G_PARM: case VIDIOC_S_PARM: retval = -EINVAL; break; default: retval = -ENOIOCTLCMD; break; } return retval; } return -EINVAL; static long cpia2_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { return video_usercopy(file, cmd, arg, cpia2_do_ioctl); if (cam->streaming) return cpia2_usb_stream_stop(cam); return -EINVAL; } /****************************************************************************** Loading Loading @@ -1550,6 +1401,33 @@ static void reset_camera_struct_v4l(struct camera_data *cam) v4l2_prio_init(&cam->prio); } static const struct v4l2_ioctl_ops cpia2_ioctl_ops = { .vidioc_querycap = cpia2_querycap, .vidioc_enum_input = cpia2_enum_input, .vidioc_g_input = cpia2_g_input, .vidioc_s_input = cpia2_s_input, .vidioc_enum_fmt_vid_cap = cpia2_enum_fmt_vid_cap, .vidioc_g_fmt_vid_cap = cpia2_g_fmt_vid_cap, .vidioc_s_fmt_vid_cap = cpia2_s_fmt_vid_cap, .vidioc_try_fmt_vid_cap = cpia2_try_fmt_vid_cap, .vidioc_queryctrl = cpia2_queryctrl, .vidioc_querymenu = cpia2_querymenu, .vidioc_g_ctrl = cpia2_g_ctrl, .vidioc_s_ctrl = cpia2_s_ctrl, .vidioc_g_jpegcomp = cpia2_g_jpegcomp, .vidioc_s_jpegcomp = cpia2_s_jpegcomp, .vidioc_cropcap = cpia2_cropcap, .vidioc_reqbufs = cpia2_reqbufs, .vidioc_querybuf = cpia2_querybuf, .vidioc_qbuf = cpia2_qbuf, .vidioc_dqbuf = cpia2_dqbuf, .vidioc_streamon = cpia2_streamon, .vidioc_streamoff = cpia2_streamoff, .vidioc_g_priority = cpia2_g_priority, .vidioc_s_priority = cpia2_s_priority, .vidioc_default = cpia2_default, }; /*** * The v4l video device structure initialized for this device ***/ Loading @@ -1559,7 +1437,7 @@ static const struct v4l2_file_operations cpia2_fops = { .release = cpia2_close, .read = cpia2_v4l_read, .poll = cpia2_v4l_poll, .unlocked_ioctl = cpia2_ioctl, .unlocked_ioctl = video_ioctl2, .mmap = cpia2_mmap, }; Loading @@ -1567,6 +1445,7 @@ static struct video_device cpia2_template = { /* I could not find any place for the old .initialize initializer?? */ .name = "CPiA2 Camera", .fops = &cpia2_fops, .ioctl_ops = &cpia2_ioctl_ops, .release = video_device_release, }; Loading