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];
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 */
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];
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 */
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];
#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
return -ENOMEM;
}
pdev->type = type_id;
- pdev->vframes = default_fps;
pdev->features = features;
pwc_construct(pdev); /* set min/max sizes correct */
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;
* 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
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
}
#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)
(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);
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);
.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,
};