diff options
Diffstat (limited to 'drivers/media/video/pwc')
-rw-r--r-- | drivers/media/video/pwc/pwc-ctrl.c | 32 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-if.c | 17 | ||||
-rw-r--r-- | drivers/media/video/pwc/pwc-v4l.c | 61 |
3 files changed, 82 insertions, 28 deletions
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 905d41d90c6a..c6dea6bc3225 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c @@ -194,8 +194,12 @@ static int set_video_mode_Nala(struct pwc_device *pdev, int size, int frames, 7 /* 30 */ }; - if (size < 0 || size > PSZ_CIF || frames < 4 || frames > 25) + if (size < 0 || size > PSZ_CIF) return -EINVAL; + if (frames < 4) + frames = 4; + else if (frames > 25) + frames = 25; frames = frames2frames[frames]; fps = frames2table[frames]; pEntry = &Nala_table[size][fps]; @@ -250,11 +254,14 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, const struct Timon_table_entry *pChoose; int ret, fps; - if (size >= PSZ_MAX || frames < 5 || frames > 30 || - *compression < 0 || *compression > 3) - return -EINVAL; - if (size == PSZ_VGA && frames > 15) + if (size >= PSZ_MAX || *compression < 0 || *compression > 3) return -EINVAL; + if (frames < 5) + frames = 5; + else if (size == PSZ_VGA && frames > 15) + frames = 15; + else if (frames > 30) + frames = 30; fps = (frames / 5) - 1; /* Find a supported framerate with progressively higher compression */ @@ -283,7 +290,7 @@ static int set_video_mode_Timon(struct pwc_device *pdev, int size, int frames, memcpy(pdev->cmd_buf, buf, 13); /* Set various parameters */ - pdev->vframes = frames; + pdev->vframes = (fps + 1) * 5; pdev->valternate = pChoose->alternate; pdev->width = pwc_image_sizes[size][0]; pdev->height = pwc_image_sizes[size][1]; @@ -303,11 +310,14 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, int fps, ret; unsigned char buf[12]; - if (size >= PSZ_MAX || frames < 5 || frames > 30 || - *compression < 0 || *compression > 3) - return -EINVAL; - if (size == PSZ_VGA && frames > 15) + if (size >= PSZ_MAX || *compression < 0 || *compression > 3) return -EINVAL; + if (frames < 5) + frames = 5; + else if (size == PSZ_VGA && frames > 15) + frames = 15; + else if (frames > 30) + frames = 30; fps = (frames / 5) - 1; /* Find a supported framerate with progressively higher compression */ @@ -339,7 +349,7 @@ static int set_video_mode_Kiara(struct pwc_device *pdev, int size, int frames, pdev->cmd_len = 12; memcpy(pdev->cmd_buf, buf, 12); /* All set and go */ - pdev->vframes = frames; + pdev->vframes = (fps + 1) * 5; pdev->valternate = pChoose->alternate; pdev->width = pwc_image_sizes[size][0]; pdev->height = pwc_image_sizes[size][1]; diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 943d37ad0d33..5592068b2f92 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -128,7 +128,6 @@ static struct usb_driver pwc_driver = { #define MAX_DEV_HINTS 20 #define MAX_ISOC_ERRORS 20 -static int default_fps = 10; #ifdef CONFIG_USB_PWC_DEBUG int pwc_trace = PWC_DEBUG_LEVEL; #endif @@ -1076,7 +1075,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id return -ENOMEM; } pdev->type = type_id; - pdev->vframes = default_fps; pdev->features = features; pwc_construct(pdev); /* set min/max sizes correct */ @@ -1138,8 +1136,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id pwc_set_leds(pdev, 0, 0); /* Setup intial videomode */ - rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, pdev->vframes, - &compression); + rc = pwc_set_video_mode(pdev, MAX_WIDTH, MAX_HEIGHT, 30, &compression); if (rc) goto err_free_mem; @@ -1243,13 +1240,11 @@ static void usb_pwc_disconnect(struct usb_interface *intf) * Initialization code & module stuff */ -static int fps; static int leds[2] = { -1, -1 }; static unsigned int leds_nargs; static char *dev_hint[MAX_DEV_HINTS]; static unsigned int dev_hint_nargs; -module_param(fps, int, 0444); #ifdef CONFIG_USB_PWC_DEBUG module_param_named(trace, pwc_trace, int, 0644); #endif @@ -1257,7 +1252,6 @@ module_param(power_save, int, 0644); module_param_array(leds, int, &leds_nargs, 0444); module_param_array(dev_hint, charp, &dev_hint_nargs, 0444); -MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30"); #ifdef CONFIG_USB_PWC_DEBUG MODULE_PARM_DESC(trace, "For debugging purposes"); #endif @@ -1286,15 +1280,6 @@ static int __init usb_pwc_init(void) } #endif - if (fps) { - if (fps < 4 || fps > 30) { - PWC_ERROR("Framerate out of bounds (4-30).\n"); - return -EINVAL; - } - default_fps = fps; - PWC_DEBUG_MODULE("Default framerate set to %d.\n", default_fps); - } - if (leds[0] >= 0) led_on = leds[0]; if (leds[1] >= 0) diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c index 80e25842e84a..ef422d0ac599 100644 --- a/drivers/media/video/pwc/pwc-v4l.c +++ b/drivers/media/video/pwc/pwc-v4l.c @@ -493,7 +493,7 @@ static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) (pixelformat>>24)&255); ret = pwc_set_video_mode(pdev, f->fmt.pix.width, f->fmt.pix.height, - pdev->vframes, &compression); + 30, &compression); PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret); @@ -1094,6 +1094,63 @@ static int pwc_enum_frameintervals(struct file *file, void *fh, return 0; } +static int pwc_g_parm(struct file *file, void *fh, + struct v4l2_streamparm *parm) +{ + struct pwc_device *pdev = video_drvdata(file); + + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + return -EINVAL; + + memset(parm, 0, sizeof(*parm)); + + parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + parm->parm.capture.readbuffers = MIN_FRAMES; + parm->parm.capture.capability |= V4L2_CAP_TIMEPERFRAME; + parm->parm.capture.timeperframe.denominator = pdev->vframes; + parm->parm.capture.timeperframe.numerator = 1; + + return 0; +} + +static int pwc_s_parm(struct file *file, void *fh, + struct v4l2_streamparm *parm) +{ + struct pwc_device *pdev = video_drvdata(file); + int compression = 0; + int ret, fps; + + if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || + parm->parm.capture.timeperframe.numerator == 0) + return -EINVAL; + + if (pwc_test_n_set_capt_file(pdev, file)) + return -EBUSY; + + fps = parm->parm.capture.timeperframe.denominator / + parm->parm.capture.timeperframe.numerator; + + mutex_lock(&pdev->udevlock); + if (!pdev->udev) { + ret = -ENODEV; + goto leave; + } + + if (pdev->iso_init) { + ret = -EBUSY; + goto leave; + } + + ret = pwc_set_video_mode(pdev, pdev->width, pdev->height, fps, + &compression); + + pwc_g_parm(file, fh, parm); + +leave: + mutex_unlock(&pdev->udevlock); + return ret; +} + static int pwc_log_status(struct file *file, void *priv) { struct pwc_device *pdev = video_drvdata(file); @@ -1120,4 +1177,6 @@ const struct v4l2_ioctl_ops pwc_ioctl_ops = { .vidioc_log_status = pwc_log_status, .vidioc_enum_framesizes = pwc_enum_framesizes, .vidioc_enum_frameintervals = pwc_enum_frameintervals, + .vidioc_g_parm = pwc_g_parm, + .vidioc_s_parm = pwc_s_parm, }; |