aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common/saa7146_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/common/saa7146_video.c')
-rw-r--r--drivers/media/common/saa7146_video.c367
1 files changed, 132 insertions, 235 deletions
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index ce30533fd972..6d14785d4747 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -2,6 +2,8 @@
2 2
3#include <media/saa7146_vv.h> 3#include <media/saa7146_vv.h>
4#include <media/v4l2-chip-ident.h> 4#include <media/v4l2-chip-ident.h>
5#include <media/v4l2-event.h>
6#include <media/v4l2-ctrls.h>
5#include <linux/module.h> 7#include <linux/module.h>
6 8
7static int max_memory = 32; 9static int max_memory = 32;
@@ -112,8 +114,8 @@ int saa7146_start_preview(struct saa7146_fh *fh)
112 114
113 DEB_EE("dev:%p, fh:%p\n", dev, fh); 115 DEB_EE("dev:%p, fh:%p\n", dev, fh);
114 116
115 /* check if we have overlay informations */ 117 /* check if we have overlay information */
116 if( NULL == fh->ov.fh ) { 118 if (vv->ov.fh == NULL) {
117 DEB_D("no overlay data available. try S_FMT first.\n"); 119 DEB_D("no overlay data available. try S_FMT first.\n");
118 return -EAGAIN; 120 return -EAGAIN;
119 } 121 }
@@ -139,19 +141,18 @@ int saa7146_start_preview(struct saa7146_fh *fh)
139 return -EBUSY; 141 return -EBUSY;
140 } 142 }
141 143
142 fmt.fmt.win = fh->ov.win; 144 fmt.fmt.win = vv->ov.win;
143 err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt); 145 err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt);
144 if (0 != err) { 146 if (0 != err) {
145 saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP); 147 saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
146 return -EBUSY; 148 return -EBUSY;
147 } 149 }
148 fh->ov.win = fmt.fmt.win; 150 vv->ov.win = fmt.fmt.win;
149 vv->ov_data = &fh->ov;
150 151
151 DEB_D("%dx%d+%d+%d %s field=%s\n", 152 DEB_D("%dx%d+%d+%d %s field=%s\n",
152 fh->ov.win.w.width, fh->ov.win.w.height, 153 vv->ov.win.w.width, vv->ov.win.w.height,
153 fh->ov.win.w.left, fh->ov.win.w.top, 154 vv->ov.win.w.left, vv->ov.win.w.top,
154 vv->ov_fmt->name, v4l2_field_names[fh->ov.win.field]); 155 vv->ov_fmt->name, v4l2_field_names[vv->ov.win.field]);
155 156
156 if (0 != (ret = saa7146_enable_overlay(fh))) { 157 if (0 != (ret = saa7146_enable_overlay(fh))) {
157 DEB_D("enabling overlay failed: %d\n", ret); 158 DEB_D("enabling overlay failed: %d\n", ret);
@@ -202,65 +203,6 @@ int saa7146_stop_preview(struct saa7146_fh *fh)
202EXPORT_SYMBOL_GPL(saa7146_stop_preview); 203EXPORT_SYMBOL_GPL(saa7146_stop_preview);
203 204
204/********************************************************************************/ 205/********************************************************************************/
205/* device controls */
206
207static struct v4l2_queryctrl controls[] = {
208 {
209 .id = V4L2_CID_BRIGHTNESS,
210 .name = "Brightness",
211 .minimum = 0,
212 .maximum = 255,
213 .step = 1,
214 .default_value = 128,
215 .type = V4L2_CTRL_TYPE_INTEGER,
216 .flags = V4L2_CTRL_FLAG_SLIDER,
217 },{
218 .id = V4L2_CID_CONTRAST,
219 .name = "Contrast",
220 .minimum = 0,
221 .maximum = 127,
222 .step = 1,
223 .default_value = 64,
224 .type = V4L2_CTRL_TYPE_INTEGER,
225 .flags = V4L2_CTRL_FLAG_SLIDER,
226 },{
227 .id = V4L2_CID_SATURATION,
228 .name = "Saturation",
229 .minimum = 0,
230 .maximum = 127,
231 .step = 1,
232 .default_value = 64,
233 .type = V4L2_CTRL_TYPE_INTEGER,
234 .flags = V4L2_CTRL_FLAG_SLIDER,
235 },{
236 .id = V4L2_CID_VFLIP,
237 .name = "Vertical Flip",
238 .minimum = 0,
239 .maximum = 1,
240 .type = V4L2_CTRL_TYPE_BOOLEAN,
241 },{
242 .id = V4L2_CID_HFLIP,
243 .name = "Horizontal Flip",
244 .minimum = 0,
245 .maximum = 1,
246 .type = V4L2_CTRL_TYPE_BOOLEAN,
247 },
248};
249static int NUM_CONTROLS = sizeof(controls)/sizeof(struct v4l2_queryctrl);
250
251#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 0)
252
253static struct v4l2_queryctrl* ctrl_by_id(int id)
254{
255 int i;
256
257 for (i = 0; i < NUM_CONTROLS; i++)
258 if (controls[i].id == id)
259 return controls+i;
260 return NULL;
261}
262
263/********************************************************************************/
264/* common pagetable functions */ 206/* common pagetable functions */
265 207
266static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf) 208static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf)
@@ -413,7 +355,7 @@ static int video_begin(struct saa7146_fh *fh)
413 } 355 }
414 } 356 }
415 357
416 fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); 358 fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
417 /* we need to have a valid format set here */ 359 /* we need to have a valid format set here */
418 BUG_ON(NULL == fmt); 360 BUG_ON(NULL == fmt);
419 361
@@ -465,7 +407,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
465 return -EBUSY; 407 return -EBUSY;
466 } 408 }
467 409
468 fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); 410 fmt = saa7146_format_by_fourcc(dev, vv->video_fmt.pixelformat);
469 /* we need to have a valid format set here */ 411 /* we need to have a valid format set here */
470 BUG_ON(NULL == fmt); 412 BUG_ON(NULL == fmt);
471 413
@@ -504,18 +446,25 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
504 446
505static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 447static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
506{ 448{
449 struct video_device *vdev = video_devdata(file);
507 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 450 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
508 451
509 strcpy((char *)cap->driver, "saa7146 v4l2"); 452 strcpy((char *)cap->driver, "saa7146 v4l2");
510 strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); 453 strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
511 sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci)); 454 sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
512 cap->version = SAA7146_VERSION_CODE; 455 cap->device_caps =
513 cap->capabilities =
514 V4L2_CAP_VIDEO_CAPTURE | 456 V4L2_CAP_VIDEO_CAPTURE |
515 V4L2_CAP_VIDEO_OVERLAY | 457 V4L2_CAP_VIDEO_OVERLAY |
516 V4L2_CAP_READWRITE | 458 V4L2_CAP_READWRITE |
517 V4L2_CAP_STREAMING; 459 V4L2_CAP_STREAMING;
518 cap->capabilities |= dev->ext_vv_data->capabilities; 460 cap->device_caps |= dev->ext_vv_data->capabilities;
461 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
462 if (vdev->vfl_type == VFL_TYPE_GRABBER)
463 cap->device_caps &=
464 ~(V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT);
465 else
466 cap->device_caps &=
467 ~(V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_AUDIO);
519 return 0; 468 return 0;
520} 469}
521 470
@@ -526,6 +475,7 @@ static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f
526 475
527 *fb = vv->ov_fb; 476 *fb = vv->ov_fb;
528 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; 477 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
478 fb->flags = V4L2_FBUF_FLAG_PRIMARY;
529 return 0; 479 return 0;
530} 480}
531 481
@@ -579,135 +529,58 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtd
579 return 0; 529 return 0;
580} 530}
581 531
582static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) 532int saa7146_s_ctrl(struct v4l2_ctrl *ctrl)
583{ 533{
584 const struct v4l2_queryctrl *ctrl; 534 struct saa7146_dev *dev = container_of(ctrl->handler,
585 535 struct saa7146_dev, ctrl_handler);
586 if ((c->id < V4L2_CID_BASE ||
587 c->id >= V4L2_CID_LASTP1) &&
588 (c->id < V4L2_CID_PRIVATE_BASE ||
589 c->id >= V4L2_CID_PRIVATE_LASTP1))
590 return -EINVAL;
591
592 ctrl = ctrl_by_id(c->id);
593 if (ctrl == NULL)
594 return -EINVAL;
595
596 DEB_EE("VIDIOC_QUERYCTRL: id:%d\n", c->id);
597 *c = *ctrl;
598 return 0;
599}
600
601static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
602{
603 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
604 struct saa7146_vv *vv = dev->vv_data; 536 struct saa7146_vv *vv = dev->vv_data;
605 const struct v4l2_queryctrl *ctrl; 537 u32 val;
606 u32 value = 0;
607 538
608 ctrl = ctrl_by_id(c->id); 539 switch (ctrl->id) {
609 if (NULL == ctrl)
610 return -EINVAL;
611 switch (c->id) {
612 case V4L2_CID_BRIGHTNESS: 540 case V4L2_CID_BRIGHTNESS:
613 value = saa7146_read(dev, BCS_CTRL); 541 val = saa7146_read(dev, BCS_CTRL);
614 c->value = 0xff & (value >> 24); 542 val &= 0x00ffffff;
615 DEB_D("V4L2_CID_BRIGHTNESS: %d\n", c->value); 543 val |= (ctrl->val << 24);
616 break; 544 saa7146_write(dev, BCS_CTRL, val);
617 case V4L2_CID_CONTRAST:
618 value = saa7146_read(dev, BCS_CTRL);
619 c->value = 0x7f & (value >> 16);
620 DEB_D("V4L2_CID_CONTRAST: %d\n", c->value);
621 break;
622 case V4L2_CID_SATURATION:
623 value = saa7146_read(dev, BCS_CTRL);
624 c->value = 0x7f & (value >> 0);
625 DEB_D("V4L2_CID_SATURATION: %d\n", c->value);
626 break;
627 case V4L2_CID_VFLIP:
628 c->value = vv->vflip;
629 DEB_D("V4L2_CID_VFLIP: %d\n", c->value);
630 break;
631 case V4L2_CID_HFLIP:
632 c->value = vv->hflip;
633 DEB_D("V4L2_CID_HFLIP: %d\n", c->value);
634 break;
635 default:
636 return -EINVAL;
637 }
638 return 0;
639}
640
641static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
642{
643 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
644 struct saa7146_vv *vv = dev->vv_data;
645 const struct v4l2_queryctrl *ctrl;
646
647 ctrl = ctrl_by_id(c->id);
648 if (NULL == ctrl) {
649 DEB_D("unknown control %d\n", c->id);
650 return -EINVAL;
651 }
652
653 switch (ctrl->type) {
654 case V4L2_CTRL_TYPE_BOOLEAN:
655 case V4L2_CTRL_TYPE_MENU:
656 case V4L2_CTRL_TYPE_INTEGER:
657 if (c->value < ctrl->minimum)
658 c->value = ctrl->minimum;
659 if (c->value > ctrl->maximum)
660 c->value = ctrl->maximum;
661 break;
662 default:
663 /* nothing */;
664 }
665
666 switch (c->id) {
667 case V4L2_CID_BRIGHTNESS: {
668 u32 value = saa7146_read(dev, BCS_CTRL);
669 value &= 0x00ffffff;
670 value |= (c->value << 24);
671 saa7146_write(dev, BCS_CTRL, value);
672 saa7146_write(dev, MC2, MASK_22 | MASK_06); 545 saa7146_write(dev, MC2, MASK_22 | MASK_06);
673 break; 546 break;
674 } 547
675 case V4L2_CID_CONTRAST: { 548 case V4L2_CID_CONTRAST:
676 u32 value = saa7146_read(dev, BCS_CTRL); 549 val = saa7146_read(dev, BCS_CTRL);
677 value &= 0xff00ffff; 550 val &= 0xff00ffff;
678 value |= (c->value << 16); 551 val |= (ctrl->val << 16);
679 saa7146_write(dev, BCS_CTRL, value); 552 saa7146_write(dev, BCS_CTRL, val);
680 saa7146_write(dev, MC2, MASK_22 | MASK_06); 553 saa7146_write(dev, MC2, MASK_22 | MASK_06);
681 break; 554 break;
682 } 555
683 case V4L2_CID_SATURATION: { 556 case V4L2_CID_SATURATION:
684 u32 value = saa7146_read(dev, BCS_CTRL); 557 val = saa7146_read(dev, BCS_CTRL);
685 value &= 0xffffff00; 558 val &= 0xffffff00;
686 value |= (c->value << 0); 559 val |= (ctrl->val << 0);
687 saa7146_write(dev, BCS_CTRL, value); 560 saa7146_write(dev, BCS_CTRL, val);
688 saa7146_write(dev, MC2, MASK_22 | MASK_06); 561 saa7146_write(dev, MC2, MASK_22 | MASK_06);
689 break; 562 break;
690 } 563
691 case V4L2_CID_HFLIP: 564 case V4L2_CID_HFLIP:
692 /* fixme: we can support changing VFLIP and HFLIP here... */ 565 /* fixme: we can support changing VFLIP and HFLIP here... */
693 if (IS_CAPTURE_ACTIVE(fh) != 0) { 566 if ((vv->video_status & STATUS_CAPTURE))
694 DEB_D("V4L2_CID_HFLIP while active capture\n");
695 return -EBUSY; 567 return -EBUSY;
696 } 568 vv->hflip = ctrl->val;
697 vv->hflip = c->value;
698 break; 569 break;
570
699 case V4L2_CID_VFLIP: 571 case V4L2_CID_VFLIP:
700 if (IS_CAPTURE_ACTIVE(fh) != 0) { 572 if ((vv->video_status & STATUS_CAPTURE))
701 DEB_D("V4L2_CID_VFLIP while active capture\n");
702 return -EBUSY; 573 return -EBUSY;
703 } 574 vv->vflip = ctrl->val;
704 vv->vflip = c->value;
705 break; 575 break;
576
706 default: 577 default:
707 return -EINVAL; 578 return -EINVAL;
708 } 579 }
709 580
710 if (IS_OVERLAY_ACTIVE(fh) != 0) { 581 if ((vv->video_status & STATUS_OVERLAY) != 0) { /* CHECK: && (vv->video_fh == fh)) */
582 struct saa7146_fh *fh = vv->video_fh;
583
711 saa7146_stop_preview(fh); 584 saa7146_stop_preview(fh);
712 saa7146_start_preview(fh); 585 saa7146_start_preview(fh);
713 } 586 }
@@ -720,6 +593,8 @@ static int vidioc_g_parm(struct file *file, void *fh,
720 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 593 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
721 struct saa7146_vv *vv = dev->vv_data; 594 struct saa7146_vv *vv = dev->vv_data;
722 595
596 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
597 return -EINVAL;
723 parm->parm.capture.readbuffers = 1; 598 parm->parm.capture.readbuffers = 1;
724 v4l2_video_std_frame_period(vv->standard->id, 599 v4l2_video_std_frame_period(vv->standard->id,
725 &parm->parm.capture.timeperframe); 600 &parm->parm.capture.timeperframe);
@@ -728,19 +603,28 @@ static int vidioc_g_parm(struct file *file, void *fh,
728 603
729static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) 604static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
730{ 605{
731 f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt; 606 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
607 struct saa7146_vv *vv = dev->vv_data;
608
609 f->fmt.pix = vv->video_fmt;
732 return 0; 610 return 0;
733} 611}
734 612
735static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) 613static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
736{ 614{
737 f->fmt.win = ((struct saa7146_fh *)fh)->ov.win; 615 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
616 struct saa7146_vv *vv = dev->vv_data;
617
618 f->fmt.win = vv->ov.win;
738 return 0; 619 return 0;
739} 620}
740 621
741static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f) 622static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
742{ 623{
743 f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt; 624 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
625 struct saa7146_vv *vv = dev->vv_data;
626
627 f->fmt.vbi = vv->vbi_fmt;
744 return 0; 628 return 0;
745} 629}
746 630
@@ -787,6 +671,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma
787 } 671 }
788 672
789 f->fmt.pix.field = field; 673 f->fmt.pix.field = field;
674 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
790 if (f->fmt.pix.width > maxw) 675 if (f->fmt.pix.width > maxw)
791 f->fmt.pix.width = maxw; 676 f->fmt.pix.width = maxw;
792 if (f->fmt.pix.height > maxh) 677 if (f->fmt.pix.height > maxh)
@@ -883,9 +768,9 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_forma
883 err = vidioc_try_fmt_vid_cap(file, fh, f); 768 err = vidioc_try_fmt_vid_cap(file, fh, f);
884 if (0 != err) 769 if (0 != err)
885 return err; 770 return err;
886 fh->video_fmt = f->fmt.pix; 771 vv->video_fmt = f->fmt.pix;
887 DEB_EE("set to pixelformat '%4.4s'\n", 772 DEB_EE("set to pixelformat '%4.4s'\n",
888 (char *)&fh->video_fmt.pixelformat); 773 (char *)&vv->video_fmt.pixelformat);
889 return 0; 774 return 0;
890} 775}
891 776
@@ -900,17 +785,17 @@ static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_f
900 err = vidioc_try_fmt_vid_overlay(file, fh, f); 785 err = vidioc_try_fmt_vid_overlay(file, fh, f);
901 if (0 != err) 786 if (0 != err)
902 return err; 787 return err;
903 fh->ov.win = f->fmt.win; 788 vv->ov.win = f->fmt.win;
904 fh->ov.nclips = f->fmt.win.clipcount; 789 vv->ov.nclips = f->fmt.win.clipcount;
905 if (fh->ov.nclips > 16) 790 if (vv->ov.nclips > 16)
906 fh->ov.nclips = 16; 791 vv->ov.nclips = 16;
907 if (copy_from_user(fh->ov.clips, f->fmt.win.clips, 792 if (copy_from_user(vv->ov.clips, f->fmt.win.clips,
908 sizeof(struct v4l2_clip) * fh->ov.nclips)) { 793 sizeof(struct v4l2_clip) * vv->ov.nclips)) {
909 return -EFAULT; 794 return -EFAULT;
910 } 795 }
911 796
912 /* fh->ov.fh is used to indicate that we have valid overlay informations, too */ 797 /* vv->ov.fh is used to indicate that we have valid overlay informations, too */
913 fh->ov.fh = fh; 798 vv->ov.fh = fh;
914 799
915 /* check if our current overlay is active */ 800 /* check if our current overlay is active */
916 if (IS_OVERLAY_ACTIVE(fh) != 0) { 801 if (IS_OVERLAY_ACTIVE(fh) != 0) {
@@ -1111,10 +996,14 @@ static int vidioc_g_chip_ident(struct file *file, void *__fh,
1111 996
1112 chip->ident = V4L2_IDENT_NONE; 997 chip->ident = V4L2_IDENT_NONE;
1113 chip->revision = 0; 998 chip->revision = 0;
1114 if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) { 999 if (chip->match.type == V4L2_CHIP_MATCH_HOST) {
1115 chip->ident = V4L2_IDENT_SAA7146; 1000 if (v4l2_chip_match_host(&chip->match))
1001 chip->ident = V4L2_IDENT_SAA7146;
1116 return 0; 1002 return 0;
1117 } 1003 }
1004 if (chip->match.type != V4L2_CHIP_MATCH_I2C_DRIVER &&
1005 chip->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
1006 return -EINVAL;
1118 return v4l2_device_call_until_err(&dev->v4l2_dev, 0, 1007 return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
1119 core, g_chip_ident, chip); 1008 core, g_chip_ident, chip);
1120} 1009}
@@ -1129,7 +1018,6 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
1129 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay, 1018 .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
1130 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, 1019 .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
1131 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, 1020 .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
1132 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
1133 .vidioc_g_chip_ident = vidioc_g_chip_ident, 1021 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1134 1022
1135 .vidioc_overlay = vidioc_overlay, 1023 .vidioc_overlay = vidioc_overlay,
@@ -1141,12 +1029,29 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
1141 .vidioc_dqbuf = vidioc_dqbuf, 1029 .vidioc_dqbuf = vidioc_dqbuf,
1142 .vidioc_g_std = vidioc_g_std, 1030 .vidioc_g_std = vidioc_g_std,
1143 .vidioc_s_std = vidioc_s_std, 1031 .vidioc_s_std = vidioc_s_std,
1144 .vidioc_queryctrl = vidioc_queryctrl,
1145 .vidioc_g_ctrl = vidioc_g_ctrl,
1146 .vidioc_s_ctrl = vidioc_s_ctrl,
1147 .vidioc_streamon = vidioc_streamon, 1032 .vidioc_streamon = vidioc_streamon,
1148 .vidioc_streamoff = vidioc_streamoff, 1033 .vidioc_streamoff = vidioc_streamoff,
1149 .vidioc_g_parm = vidioc_g_parm, 1034 .vidioc_g_parm = vidioc_g_parm,
1035 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1036 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1037};
1038
1039const struct v4l2_ioctl_ops saa7146_vbi_ioctl_ops = {
1040 .vidioc_querycap = vidioc_querycap,
1041 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
1042 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1043
1044 .vidioc_reqbufs = vidioc_reqbufs,
1045 .vidioc_querybuf = vidioc_querybuf,
1046 .vidioc_qbuf = vidioc_qbuf,
1047 .vidioc_dqbuf = vidioc_dqbuf,
1048 .vidioc_g_std = vidioc_g_std,
1049 .vidioc_s_std = vidioc_s_std,
1050 .vidioc_streamon = vidioc_streamon,
1051 .vidioc_streamoff = vidioc_streamoff,
1052 .vidioc_g_parm = vidioc_g_parm,
1053 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1054 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1150}; 1055};
1151 1056
1152/*********************************************************************************/ 1057/*********************************************************************************/
@@ -1161,7 +1066,7 @@ static int buffer_activate (struct saa7146_dev *dev,
1161 buf->vb.state = VIDEOBUF_ACTIVE; 1066 buf->vb.state = VIDEOBUF_ACTIVE;
1162 saa7146_set_capture(dev,buf,next); 1067 saa7146_set_capture(dev,buf,next);
1163 1068
1164 mod_timer(&vv->video_q.timeout, jiffies+BUFFER_TIMEOUT); 1069 mod_timer(&vv->video_dmaq.timeout, jiffies+BUFFER_TIMEOUT);
1165 return 0; 1070 return 0;
1166} 1071}
1167 1072
@@ -1185,44 +1090,44 @@ static int buffer_prepare(struct videobuf_queue *q,
1185 DEB_CAP("vbuf:%p\n", vb); 1090 DEB_CAP("vbuf:%p\n", vb);
1186 1091
1187 /* sanity checks */ 1092 /* sanity checks */
1188 if (fh->video_fmt.width < 48 || 1093 if (vv->video_fmt.width < 48 ||
1189 fh->video_fmt.height < 32 || 1094 vv->video_fmt.height < 32 ||
1190 fh->video_fmt.width > vv->standard->h_max_out || 1095 vv->video_fmt.width > vv->standard->h_max_out ||
1191 fh->video_fmt.height > vv->standard->v_max_out) { 1096 vv->video_fmt.height > vv->standard->v_max_out) {
1192 DEB_D("w (%d) / h (%d) out of bounds\n", 1097 DEB_D("w (%d) / h (%d) out of bounds\n",
1193 fh->video_fmt.width, fh->video_fmt.height); 1098 vv->video_fmt.width, vv->video_fmt.height);
1194 return -EINVAL; 1099 return -EINVAL;
1195 } 1100 }
1196 1101
1197 size = fh->video_fmt.sizeimage; 1102 size = vv->video_fmt.sizeimage;
1198 if (0 != buf->vb.baddr && buf->vb.bsize < size) { 1103 if (0 != buf->vb.baddr && buf->vb.bsize < size) {
1199 DEB_D("size mismatch\n"); 1104 DEB_D("size mismatch\n");
1200 return -EINVAL; 1105 return -EINVAL;
1201 } 1106 }
1202 1107
1203 DEB_CAP("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n", 1108 DEB_CAP("buffer_prepare [size=%dx%d,bytes=%d,fields=%s]\n",
1204 fh->video_fmt.width, fh->video_fmt.height, 1109 vv->video_fmt.width, vv->video_fmt.height,
1205 size, v4l2_field_names[fh->video_fmt.field]); 1110 size, v4l2_field_names[vv->video_fmt.field]);
1206 if (buf->vb.width != fh->video_fmt.width || 1111 if (buf->vb.width != vv->video_fmt.width ||
1207 buf->vb.bytesperline != fh->video_fmt.bytesperline || 1112 buf->vb.bytesperline != vv->video_fmt.bytesperline ||
1208 buf->vb.height != fh->video_fmt.height || 1113 buf->vb.height != vv->video_fmt.height ||
1209 buf->vb.size != size || 1114 buf->vb.size != size ||
1210 buf->vb.field != field || 1115 buf->vb.field != field ||
1211 buf->vb.field != fh->video_fmt.field || 1116 buf->vb.field != vv->video_fmt.field ||
1212 buf->fmt != &fh->video_fmt) { 1117 buf->fmt != &vv->video_fmt) {
1213 saa7146_dma_free(dev,q,buf); 1118 saa7146_dma_free(dev,q,buf);
1214 } 1119 }
1215 1120
1216 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 1121 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
1217 struct saa7146_format *sfmt; 1122 struct saa7146_format *sfmt;
1218 1123
1219 buf->vb.bytesperline = fh->video_fmt.bytesperline; 1124 buf->vb.bytesperline = vv->video_fmt.bytesperline;
1220 buf->vb.width = fh->video_fmt.width; 1125 buf->vb.width = vv->video_fmt.width;
1221 buf->vb.height = fh->video_fmt.height; 1126 buf->vb.height = vv->video_fmt.height;
1222 buf->vb.size = size; 1127 buf->vb.size = size;
1223 buf->vb.field = field; 1128 buf->vb.field = field;
1224 buf->fmt = &fh->video_fmt; 1129 buf->fmt = &vv->video_fmt;
1225 buf->vb.field = fh->video_fmt.field; 1130 buf->vb.field = vv->video_fmt.field;
1226 1131
1227 sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); 1132 sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat);
1228 1133
@@ -1258,11 +1163,12 @@ static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned
1258{ 1163{
1259 struct file *file = q->priv_data; 1164 struct file *file = q->priv_data;
1260 struct saa7146_fh *fh = file->private_data; 1165 struct saa7146_fh *fh = file->private_data;
1166 struct saa7146_vv *vv = fh->dev->vv_data;
1261 1167
1262 if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS) 1168 if (0 == *count || *count > MAX_SAA7146_CAPTURE_BUFFERS)
1263 *count = MAX_SAA7146_CAPTURE_BUFFERS; 1169 *count = MAX_SAA7146_CAPTURE_BUFFERS;
1264 1170
1265 *size = fh->video_fmt.sizeimage; 1171 *size = vv->video_fmt.sizeimage;
1266 1172
1267 /* check if we exceed the "max_memory" parameter */ 1173 /* check if we exceed the "max_memory" parameter */
1268 if( (*count * *size) > (max_memory*1048576) ) { 1174 if( (*count * *size) > (max_memory*1048576) ) {
@@ -1283,7 +1189,7 @@ static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1283 struct saa7146_buf *buf = (struct saa7146_buf *)vb; 1189 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1284 1190
1285 DEB_CAP("vbuf:%p\n", vb); 1191 DEB_CAP("vbuf:%p\n", vb);
1286 saa7146_buffer_queue(fh->dev,&vv->video_q,buf); 1192 saa7146_buffer_queue(fh->dev, &vv->video_dmaq, buf);
1287} 1193}
1288 1194
1289static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) 1195static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
@@ -1312,12 +1218,12 @@ static struct videobuf_queue_ops video_qops = {
1312 1218
1313static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv) 1219static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
1314{ 1220{
1315 INIT_LIST_HEAD(&vv->video_q.queue); 1221 INIT_LIST_HEAD(&vv->video_dmaq.queue);
1316 1222
1317 init_timer(&vv->video_q.timeout); 1223 init_timer(&vv->video_dmaq.timeout);
1318 vv->video_q.timeout.function = saa7146_buffer_timeout; 1224 vv->video_dmaq.timeout.function = saa7146_buffer_timeout;
1319 vv->video_q.timeout.data = (unsigned long)(&vv->video_q); 1225 vv->video_dmaq.timeout.data = (unsigned long)(&vv->video_dmaq);
1320 vv->video_q.dev = dev; 1226 vv->video_dmaq.dev = dev;
1321 1227
1322 /* set some default values */ 1228 /* set some default values */
1323 vv->standard = &dev->ext_vv_data->stds[0]; 1229 vv->standard = &dev->ext_vv_data->stds[0];
@@ -1331,15 +1237,6 @@ static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
1331static int video_open(struct saa7146_dev *dev, struct file *file) 1237static int video_open(struct saa7146_dev *dev, struct file *file)
1332{ 1238{
1333 struct saa7146_fh *fh = file->private_data; 1239 struct saa7146_fh *fh = file->private_data;
1334 struct saa7146_format *sfmt;
1335
1336 fh->video_fmt.width = 384;
1337 fh->video_fmt.height = 288;
1338 fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
1339 fh->video_fmt.bytesperline = 0;
1340 fh->video_fmt.field = V4L2_FIELD_ANY;
1341 sfmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat);
1342 fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
1343 1240
1344 videobuf_queue_sg_init(&fh->video_q, &video_qops, 1241 videobuf_queue_sg_init(&fh->video_q, &video_qops,
1345 &dev->pci->dev, &dev->slock, 1242 &dev->pci->dev, &dev->slock,
@@ -1371,7 +1268,7 @@ static void video_close(struct saa7146_dev *dev, struct file *file)
1371static void video_irq_done(struct saa7146_dev *dev, unsigned long st) 1268static void video_irq_done(struct saa7146_dev *dev, unsigned long st)
1372{ 1269{
1373 struct saa7146_vv *vv = dev->vv_data; 1270 struct saa7146_vv *vv = dev->vv_data;
1374 struct saa7146_dmaqueue *q = &vv->video_q; 1271 struct saa7146_dmaqueue *q = &vv->video_dmaq;
1375 1272
1376 spin_lock(&dev->slock); 1273 spin_lock(&dev->slock);
1377 DEB_CAP("called\n"); 1274 DEB_CAP("called\n");