diff options
author | Jim Paris <jim@jtan.com> | 2008-12-10 04:06:20 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-12-30 06:39:02 -0500 |
commit | 11d9f25da89523d19dba3608d51a86af2954fc0d (patch) | |
tree | 2f15efad04812230e441113f952d0dd17eeb3e74 /drivers/media/video/gspca/ov534.c | |
parent | 627a5ef7893fa127925b99e2597c8210202c75aa (diff) |
V4L/DVB (9877): gspca - ov534: Add framerate support.
Add support for getting and setting framerate via v4l2 controls,
rather than setting a fixed value at module insertion.
Signed-off-by: Jim Paris <jim@jtan.com>
Signed-off-by: Jean-Francois Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/gspca/ov534.c')
-rw-r--r-- | drivers/media/video/gspca/ov534.c | 115 |
1 files changed, 78 insertions, 37 deletions
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c index 66a7bd2f6762..cd5c302d6990 100644 --- a/drivers/media/video/gspca/ov534.c +++ b/drivers/media/video/gspca/ov534.c | |||
@@ -43,14 +43,12 @@ MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); | |||
43 | MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); | 43 | MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); |
44 | MODULE_LICENSE("GPL"); | 44 | MODULE_LICENSE("GPL"); |
45 | 45 | ||
46 | /* global parameters */ | ||
47 | static int frame_rate; | ||
48 | |||
49 | /* specific webcam descriptor */ | 46 | /* specific webcam descriptor */ |
50 | struct sd { | 47 | struct sd { |
51 | struct gspca_dev gspca_dev; /* !! must be the first item */ | 48 | struct gspca_dev gspca_dev; /* !! must be the first item */ |
52 | __u32 last_fid; | 49 | __u32 last_fid; |
53 | __u32 last_pts; | 50 | __u32 last_pts; |
51 | int frame_rate; | ||
54 | }; | 52 | }; |
55 | 53 | ||
56 | /* V4L2 controls supported by the driver */ | 54 | /* V4L2 controls supported by the driver */ |
@@ -296,6 +294,40 @@ static const __u8 ov772x_reg_initdata[][2] = { | |||
296 | { 0x0c, 0xd0 } | 294 | { 0x0c, 0xd0 } |
297 | }; | 295 | }; |
298 | 296 | ||
297 | /* set framerate */ | ||
298 | static void ov534_set_frame_rate(struct gspca_dev *gspca_dev) | ||
299 | { | ||
300 | struct sd *sd = (struct sd *) gspca_dev; | ||
301 | int fr = sd->frame_rate; | ||
302 | |||
303 | switch (fr) { | ||
304 | case 50: | ||
305 | sccb_reg_write(gspca_dev->dev, 0x11, 0x01); | ||
306 | sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); | ||
307 | ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); | ||
308 | break; | ||
309 | case 40: | ||
310 | sccb_reg_write(gspca_dev->dev, 0x11, 0x02); | ||
311 | sccb_reg_write(gspca_dev->dev, 0x0d, 0xc1); | ||
312 | ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); | ||
313 | break; | ||
314 | /* case 30: */ | ||
315 | default: | ||
316 | fr = 30; | ||
317 | sccb_reg_write(gspca_dev->dev, 0x11, 0x04); | ||
318 | sccb_reg_write(gspca_dev->dev, 0x0d, 0x81); | ||
319 | ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); | ||
320 | break; | ||
321 | case 15: | ||
322 | sccb_reg_write(gspca_dev->dev, 0x11, 0x03); | ||
323 | sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); | ||
324 | ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); | ||
325 | break; | ||
326 | } | ||
327 | |||
328 | sd->frame_rate = fr; | ||
329 | PDEBUG(D_PROBE, "frame_rate: %d", fr); | ||
330 | } | ||
299 | 331 | ||
300 | /* setup method */ | 332 | /* setup method */ |
301 | static void ov534_setup(struct usb_device *udev) | 333 | static void ov534_setup(struct usb_device *udev) |
@@ -339,38 +371,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
339 | /* this function is called at probe and resume time */ | 371 | /* this function is called at probe and resume time */ |
340 | static int sd_init(struct gspca_dev *gspca_dev) | 372 | static int sd_init(struct gspca_dev *gspca_dev) |
341 | { | 373 | { |
342 | int fr; | ||
343 | |||
344 | ov534_setup(gspca_dev->dev); | 374 | ov534_setup(gspca_dev->dev); |
345 | 375 | ov534_set_frame_rate(gspca_dev); | |
346 | fr = frame_rate; | ||
347 | |||
348 | switch (fr) { | ||
349 | case 50: | ||
350 | sccb_reg_write(gspca_dev->dev, 0x11, 0x01); | ||
351 | sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); | ||
352 | ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); | ||
353 | break; | ||
354 | case 40: | ||
355 | sccb_reg_write(gspca_dev->dev, 0x11, 0x02); | ||
356 | sccb_reg_write(gspca_dev->dev, 0x0d, 0xc1); | ||
357 | ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); | ||
358 | break; | ||
359 | /* case 30: */ | ||
360 | default: | ||
361 | fr = 30; | ||
362 | sccb_reg_write(gspca_dev->dev, 0x11, 0x04); | ||
363 | sccb_reg_write(gspca_dev->dev, 0x0d, 0x81); | ||
364 | ov534_reg_write(gspca_dev->dev, 0xe5, 0x02); | ||
365 | break; | ||
366 | case 15: | ||
367 | sccb_reg_write(gspca_dev->dev, 0x11, 0x03); | ||
368 | sccb_reg_write(gspca_dev->dev, 0x0d, 0x41); | ||
369 | ov534_reg_write(gspca_dev->dev, 0xe5, 0x04); | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | PDEBUG(D_PROBE, "frame_rate: %d", fr); | ||
374 | 376 | ||
375 | return 0; | 377 | return 0; |
376 | } | 378 | } |
@@ -477,6 +479,46 @@ discard: | |||
477 | goto scan_next; | 479 | goto scan_next; |
478 | } | 480 | } |
479 | 481 | ||
482 | /* get stream parameters (framerate) */ | ||
483 | int sd_get_streamparm(struct gspca_dev *gspca_dev, | ||
484 | struct v4l2_streamparm *parm) | ||
485 | { | ||
486 | struct v4l2_captureparm *cp = &parm->parm.capture; | ||
487 | struct v4l2_fract *tpf = &cp->timeperframe; | ||
488 | struct sd *sd = (struct sd *) gspca_dev; | ||
489 | |||
490 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
491 | return -EINVAL; | ||
492 | |||
493 | cp->capability |= V4L2_CAP_TIMEPERFRAME; | ||
494 | tpf->numerator = 1; | ||
495 | tpf->denominator = sd->frame_rate; | ||
496 | |||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | /* set stream parameters (framerate) */ | ||
501 | int sd_set_streamparm(struct gspca_dev *gspca_dev, | ||
502 | struct v4l2_streamparm *parm) | ||
503 | { | ||
504 | struct v4l2_captureparm *cp = &parm->parm.capture; | ||
505 | struct v4l2_fract *tpf = &cp->timeperframe; | ||
506 | struct sd *sd = (struct sd *) gspca_dev; | ||
507 | |||
508 | if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
509 | return -EINVAL; | ||
510 | |||
511 | /* Set requested framerate */ | ||
512 | sd->frame_rate = tpf->denominator / tpf->numerator; | ||
513 | ov534_set_frame_rate(gspca_dev); | ||
514 | |||
515 | /* Return the actual framerate */ | ||
516 | tpf->numerator = 1; | ||
517 | tpf->denominator = sd->frame_rate; | ||
518 | |||
519 | return 0; | ||
520 | } | ||
521 | |||
480 | /* sub-driver description */ | 522 | /* sub-driver description */ |
481 | static const struct sd_desc sd_desc = { | 523 | static const struct sd_desc sd_desc = { |
482 | .name = MODULE_NAME, | 524 | .name = MODULE_NAME, |
@@ -487,6 +529,8 @@ static const struct sd_desc sd_desc = { | |||
487 | .start = sd_start, | 529 | .start = sd_start, |
488 | .stopN = sd_stopN, | 530 | .stopN = sd_stopN, |
489 | .pkt_scan = sd_pkt_scan, | 531 | .pkt_scan = sd_pkt_scan, |
532 | .get_streamparm = sd_get_streamparm, | ||
533 | .set_streamparm = sd_set_streamparm, | ||
490 | }; | 534 | }; |
491 | 535 | ||
492 | /* -- module initialisation -- */ | 536 | /* -- module initialisation -- */ |
@@ -534,6 +578,3 @@ static void __exit sd_mod_exit(void) | |||
534 | 578 | ||
535 | module_init(sd_mod_init); | 579 | module_init(sd_mod_init); |
536 | module_exit(sd_mod_exit); | 580 | module_exit(sd_mod_exit); |
537 | |||
538 | module_param(frame_rate, int, 0644); | ||
539 | MODULE_PARM_DESC(frame_rate, "Frame rate (15, 30, 40, 50)"); | ||