summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c')
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c146
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])) &&