diff options
Diffstat (limited to 'linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c')
-rw-r--r-- | linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 146 |
1 files changed, 107 insertions, 39 deletions
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 78cdd01c8..a74eecf87 100644 --- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -22,6 +22,7 @@ #include "compat.h" #include <linux/kernel.h> +#include <linux/version.h> #include "pvrusb2-context.h" #include "pvrusb2-hdw.h" #include "pvrusb2.h" @@ -450,12 +451,6 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, vf->fmt.pix.width = val; val = 0; pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw, - PVR2_CID_INTERLACE), - &val); - if (val) vf->fmt.pix.width /= 2; - val = 0; - pvr2_ctrl_get_value( pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES), &val); vf->fmt.pix.height = val; @@ -482,25 +477,22 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, case V4L2_BUF_TYPE_VIDEO_CAPTURE: { int h = vf->fmt.pix.height; int w = vf->fmt.pix.width; - int vd_std, hf, hh; - vd_std = 0; - pvr2_ctrl_get_value( - pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR), - &vd_std); - if (vd_std & V4L2_STD_525_60) { - hf=480; - } else { - hf=576; + if (h < 200) { + h = 200; + } else if (h > 625) { + h = 625; + } + if (w < 320) { + w = 320; + } else if (w > 720) { + w = 720; } - hh = (int) (hf / 2); memcpy(vf, &pvr_format[PVR_FORMAT_PIX], sizeof(struct v4l2_format)); - if (w > 720) - vf->fmt.pix.width = 720; - vf->fmt.pix.width &= 0xff0; - vf->fmt.pix.height = (h > hh) ? hf : hh; + vf->fmt.pix.width = w; + vf->fmt.pix.height = h; if (cmd == VIDIOC_S_FMT) { pvr2_ctrl_set_value( @@ -511,10 +503,6 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_VRES), vf->fmt.pix.height); - pvr2_ctrl_set_value( - pvr2_hdw_get_ctrl_by_id( - hdw,PVR2_CID_INTERLACE), - vf->fmt.pix.height != hf); } } break; case V4L2_BUF_TYPE_VBI_CAPTURE: @@ -547,13 +535,27 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, struct pvr2_ctrl *cptr; struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg; ret = 0; - cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id); + if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) { + cptr = pvr2_hdw_get_ctrl_nextv4l( + hdw,(vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL)); + if (cptr) vc->id = pvr2_ctrl_get_v4lid(cptr); + } else { + cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id); + } if (!cptr) { + pvr2_trace(PVR2_TRACE_V4LIOCTL, + "QUERYCTRL id=0x%x not implemented here", + vc->id); ret = -EINVAL; break; } - strlcpy(vc->name,pvr2_ctrl_get_name(cptr),sizeof(vc->name)); + pvr2_trace(PVR2_TRACE_V4LIOCTL, + "QUERYCTRL id=0x%x mapping name=%s (%s)", + vc->id,pvr2_ctrl_get_name(cptr), + pvr2_ctrl_get_desc(cptr)); + strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name)); + vc->flags = pvr2_ctrl_get_v4lflags(cptr); vc->default_value = pvr2_ctrl_get_def(cptr); switch (pvr2_ctrl_get_type(cptr)) { case pvr2_ctl_enum: @@ -562,6 +564,12 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1; vc->step = 1; break; + case pvr2_ctl_bool: + vc->type = V4L2_CTRL_TYPE_BOOLEAN; + vc->minimum = 0; + vc->maximum = 1; + vc->step = 1; + break; case pvr2_ctl_int: vc->type = V4L2_CTRL_TYPE_INTEGER; vc->minimum = pvr2_ctrl_get_min(cptr); @@ -569,6 +577,9 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, vc->step = 1; break; default: + pvr2_trace(PVR2_TRACE_V4LIOCTL, + "QUERYCTRL id=0x%x name=%s not mappable", + vc->id,pvr2_ctrl_get_name(cptr)); ret = -EINVAL; break; } @@ -605,13 +616,72 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, break; } - case VIDIOC_LOG_STATUS: + case VIDIOC_G_EXT_CTRLS: + { + struct v4l2_ext_controls *ctls = + (struct v4l2_ext_controls *)arg; + struct v4l2_ext_control *ctrl; + unsigned int idx; + int val; + for (idx = 0; idx < ctls->count; idx++) { + ctrl = ctls->controls + idx; + ret = pvr2_ctrl_get_value( + pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),&val); + if (ret) { + ctls->error_idx = idx; + break; + } + /* Ensure that if read as a 64 bit value, the user + will still get a hopefully sane value */ + ctrl->value64 = 0; + ctrl->value = val; + } + break; + } + + case VIDIOC_S_EXT_CTRLS: + { + struct v4l2_ext_controls *ctls = + (struct v4l2_ext_controls *)arg; + struct v4l2_ext_control *ctrl; + unsigned int idx; + for (idx = 0; idx < ctls->count; idx++) { + ctrl = ctls->controls + idx; + ret = pvr2_ctrl_set_value( + pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id), + ctrl->value); + if (ret) { + ctls->error_idx = idx; + break; + } + } + break; + } + + case VIDIOC_TRY_EXT_CTRLS: { - int nr = pvr2_hdw_get_unit_number(hdw); + struct v4l2_ext_controls *ctls = + (struct v4l2_ext_controls *)arg; + struct v4l2_ext_control *ctrl; + struct pvr2_ctrl *pctl; + unsigned int idx; + /* For the moment just validate that the requested control + actually exists. */ + for (idx = 0; idx < ctls->count; idx++) { + ctrl = ctls->controls + idx; + pctl = pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id); + if (!pctl) { + ret = -EINVAL; + ctls->error_idx = idx; + break; + } + } + break; + } - printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr); + case VIDIOC_LOG_STATUS: + { pvr2_hdw_trigger_module_log(hdw); - printk(KERN_INFO "pvrusb2: ================== END STATUS CARD #%d ==================\n", nr); ret = 0; break; } @@ -625,11 +695,11 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, if (ret < 0) { if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, + pvr2_trace(PVR2_TRACE_V4LIOCTL, "pvr2_v4l2_do_ioctl failure, ret=%d",ret); } else { - if (pvrusb2_debug & PVR2_TRACE_ERROR_LEGS) { - pvr2_trace(PVR2_TRACE_ERROR_LEGS, + if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) { + pvr2_trace(PVR2_TRACE_V4LIOCTL, "pvr2_v4l2_do_ioctl failure, ret=%d" " command was:",ret); v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw), @@ -647,9 +717,8 @@ static int pvr2_v4l2_do_ioctl(struct inode *inode, struct file *file, static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip) { - pvr2_trace(PVR2_TRACE_INIT, - "unregistering device video%d [%s]", - dip->vdev->minor,pvr2_config_get_name(dip->config)); + printk(KERN_INFO "pvrusb2: unregistering device video%d [%s]\n", + dip->vdev->minor,pvr2_config_get_name(dip->config)); if (dip->ctxt_idx >= 0) { mutex_lock(&device_lock); devices[dip->ctxt_idx] = NULL; @@ -1037,9 +1106,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, (video_register_device(dip->vdev, v4l_type, -1) < 0)) { err("Failed to register pvrusb2 v4l video device"); } else { - pvr2_trace(PVR2_TRACE_INIT, - "registered device video%d [%s]", - dip->vdev->minor,pvr2_config_get_name(dip->config)); + printk(KERN_INFO "pvrusb2: registered device video%d [%s]\n", + dip->vdev->minor,pvr2_config_get_name(dip->config)); } if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) && |