diff options
Diffstat (limited to 'drivers/media/common/saa7146_video.c')
-rw-r--r-- | drivers/media/common/saa7146_video.c | 367 |
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 | ||
7 | static int max_memory = 32; | 9 | static 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) | |||
202 | EXPORT_SYMBOL_GPL(saa7146_stop_preview); | 203 | EXPORT_SYMBOL_GPL(saa7146_stop_preview); |
203 | 204 | ||
204 | /********************************************************************************/ | 205 | /********************************************************************************/ |
205 | /* device controls */ | ||
206 | |||
207 | static 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 | }; | ||
249 | static int NUM_CONTROLS = sizeof(controls)/sizeof(struct v4l2_queryctrl); | ||
250 | |||
251 | #define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 0) | ||
252 | |||
253 | static 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 | ||
266 | static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf) | 208 | static 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 | ||
505 | static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap) | 447 | static 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 | ||
582 | static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) | 532 | int 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 | |||
601 | static 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 | |||
641 | static 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 | ||
729 | static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f) | 604 | static 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 | ||
735 | static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f) | 613 | static 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 | ||
741 | static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f) | 622 | static 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 | |||
1039 | const 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 | ||
1289 | static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | 1195 | static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb) |
@@ -1312,12 +1218,12 @@ static struct videobuf_queue_ops video_qops = { | |||
1312 | 1218 | ||
1313 | static void video_init(struct saa7146_dev *dev, struct saa7146_vv *vv) | 1219 | static 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) | |||
1331 | static int video_open(struct saa7146_dev *dev, struct file *file) | 1237 | static 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) | |||
1371 | static void video_irq_done(struct saa7146_dev *dev, unsigned long st) | 1268 | static 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"); |