aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/common')
-rw-r--r--drivers/media/common/saa7146_fops.c27
-rw-r--r--drivers/media/common/saa7146_video.c210
2 files changed, 65 insertions, 172 deletions
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index 8d7df1a0bcd0..f14e218bed16 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -429,8 +429,13 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
429 } 429 }
430} 430}
431 431
432static const struct v4l2_ctrl_ops saa7146_ctrl_ops = {
433 .s_ctrl = saa7146_s_ctrl,
434};
435
432int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) 436int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
433{ 437{
438 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
434 struct saa7146_vv *vv; 439 struct saa7146_vv *vv;
435 int err; 440 int err;
436 441
@@ -438,9 +443,28 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
438 if (err) 443 if (err)
439 return err; 444 return err;
440 445
446 v4l2_ctrl_handler_init(hdl, 6);
447 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
448 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
449 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
450 V4L2_CID_CONTRAST, 0, 127, 1, 64);
451 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
452 V4L2_CID_SATURATION, 0, 127, 1, 64);
453 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
454 V4L2_CID_VFLIP, 0, 1, 1, 0);
455 v4l2_ctrl_new_std(hdl, &saa7146_ctrl_ops,
456 V4L2_CID_HFLIP, 0, 1, 1, 0);
457 if (hdl->error) {
458 err = hdl->error;
459 v4l2_ctrl_handler_free(hdl);
460 return err;
461 }
462 dev->v4l2_dev.ctrl_handler = hdl;
463
441 vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL); 464 vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
442 if (vv == NULL) { 465 if (vv == NULL) {
443 ERR("out of memory. aborting.\n"); 466 ERR("out of memory. aborting.\n");
467 v4l2_ctrl_handler_free(hdl);
444 return -ENOMEM; 468 return -ENOMEM;
445 } 469 }
446 ext_vv->ops = saa7146_video_ioctl_ops; 470 ext_vv->ops = saa7146_video_ioctl_ops;
@@ -463,6 +487,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
463 if( NULL == vv->d_clipping.cpu_addr ) { 487 if( NULL == vv->d_clipping.cpu_addr ) {
464 ERR("out of memory. aborting.\n"); 488 ERR("out of memory. aborting.\n");
465 kfree(vv); 489 kfree(vv);
490 v4l2_ctrl_handler_free(hdl);
466 return -1; 491 return -1;
467 } 492 }
468 memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM); 493 memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM);
@@ -486,6 +511,7 @@ int saa7146_vv_release(struct saa7146_dev* dev)
486 511
487 v4l2_device_unregister(&dev->v4l2_dev); 512 v4l2_device_unregister(&dev->v4l2_dev);
488 pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle); 513 pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
514 v4l2_ctrl_handler_free(&dev->ctrl_handler);
489 kfree(vv); 515 kfree(vv);
490 dev->vv_data = NULL; 516 dev->vv_data = NULL;
491 dev->vv_callback = NULL; 517 dev->vv_callback = NULL;
@@ -516,6 +542,7 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
516 This driver needs auditing so that this flag can be removed. */ 542 This driver needs auditing so that this flag can be removed. */
517 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags); 543 set_bit(V4L2_FL_LOCK_ALL_FOPS, &vfd->flags);
518 vfd->lock = &dev->v4l2_lock; 544 vfd->lock = &dev->v4l2_lock;
545 vfd->v4l2_dev = &dev->v4l2_dev;
519 vfd->tvnorms = 0; 546 vfd->tvnorms = 0;
520 for (i = 0; i < dev->ext_vv_data->num_stds; i++) 547 for (i = 0; i < dev->ext_vv_data->num_stds; i++)
521 vfd->tvnorms |= dev->ext_vv_data->stds[i].id; 548 vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index ce30533fd972..8818e661a42f 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -202,65 +202,6 @@ int saa7146_stop_preview(struct saa7146_fh *fh)
202EXPORT_SYMBOL_GPL(saa7146_stop_preview); 202EXPORT_SYMBOL_GPL(saa7146_stop_preview);
203 203
204/********************************************************************************/ 204/********************************************************************************/
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 */ 205/* common pagetable functions */
265 206
266static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf) 207static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *buf)
@@ -510,12 +451,13 @@ static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *
510 strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card)); 451 strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
511 sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci)); 452 sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
512 cap->version = SAA7146_VERSION_CODE; 453 cap->version = SAA7146_VERSION_CODE;
513 cap->capabilities = 454 cap->device_caps =
514 V4L2_CAP_VIDEO_CAPTURE | 455 V4L2_CAP_VIDEO_CAPTURE |
515 V4L2_CAP_VIDEO_OVERLAY | 456 V4L2_CAP_VIDEO_OVERLAY |
516 V4L2_CAP_READWRITE | 457 V4L2_CAP_READWRITE |
517 V4L2_CAP_STREAMING; 458 V4L2_CAP_STREAMING;
518 cap->capabilities |= dev->ext_vv_data->capabilities; 459 cap->device_caps |= dev->ext_vv_data->capabilities;
460 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
519 return 0; 461 return 0;
520} 462}
521 463
@@ -579,135 +521,58 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtd
579 return 0; 521 return 0;
580} 522}
581 523
582static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c) 524int saa7146_s_ctrl(struct v4l2_ctrl *ctrl)
583{
584 const struct v4l2_queryctrl *ctrl;
585
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{ 525{
603 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 526 struct saa7146_dev *dev = container_of(ctrl->handler,
527 struct saa7146_dev, ctrl_handler);
604 struct saa7146_vv *vv = dev->vv_data; 528 struct saa7146_vv *vv = dev->vv_data;
605 const struct v4l2_queryctrl *ctrl; 529 u32 val;
606 u32 value = 0;
607 530
608 ctrl = ctrl_by_id(c->id); 531 switch (ctrl->id) {
609 if (NULL == ctrl)
610 return -EINVAL;
611 switch (c->id) {
612 case V4L2_CID_BRIGHTNESS: 532 case V4L2_CID_BRIGHTNESS:
613 value = saa7146_read(dev, BCS_CTRL); 533 val = saa7146_read(dev, BCS_CTRL);
614 c->value = 0xff & (value >> 24); 534 val &= 0x00ffffff;
615 DEB_D("V4L2_CID_BRIGHTNESS: %d\n", c->value); 535 val |= (ctrl->val << 24);
616 break; 536 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); 537 saa7146_write(dev, MC2, MASK_22 | MASK_06);
673 break; 538 break;
674 } 539
675 case V4L2_CID_CONTRAST: { 540 case V4L2_CID_CONTRAST:
676 u32 value = saa7146_read(dev, BCS_CTRL); 541 val = saa7146_read(dev, BCS_CTRL);
677 value &= 0xff00ffff; 542 val &= 0xff00ffff;
678 value |= (c->value << 16); 543 val |= (ctrl->val << 16);
679 saa7146_write(dev, BCS_CTRL, value); 544 saa7146_write(dev, BCS_CTRL, val);
680 saa7146_write(dev, MC2, MASK_22 | MASK_06); 545 saa7146_write(dev, MC2, MASK_22 | MASK_06);
681 break; 546 break;
682 } 547
683 case V4L2_CID_SATURATION: { 548 case V4L2_CID_SATURATION:
684 u32 value = saa7146_read(dev, BCS_CTRL); 549 val = saa7146_read(dev, BCS_CTRL);
685 value &= 0xffffff00; 550 val &= 0xffffff00;
686 value |= (c->value << 0); 551 val |= (ctrl->val << 0);
687 saa7146_write(dev, BCS_CTRL, value); 552 saa7146_write(dev, BCS_CTRL, val);
688 saa7146_write(dev, MC2, MASK_22 | MASK_06); 553 saa7146_write(dev, MC2, MASK_22 | MASK_06);
689 break; 554 break;
690 } 555
691 case V4L2_CID_HFLIP: 556 case V4L2_CID_HFLIP:
692 /* fixme: we can support changing VFLIP and HFLIP here... */ 557 /* fixme: we can support changing VFLIP and HFLIP here... */
693 if (IS_CAPTURE_ACTIVE(fh) != 0) { 558 if ((vv->video_status & STATUS_CAPTURE))
694 DEB_D("V4L2_CID_HFLIP while active capture\n");
695 return -EBUSY; 559 return -EBUSY;
696 } 560 vv->hflip = ctrl->val;
697 vv->hflip = c->value;
698 break; 561 break;
562
699 case V4L2_CID_VFLIP: 563 case V4L2_CID_VFLIP:
700 if (IS_CAPTURE_ACTIVE(fh) != 0) { 564 if ((vv->video_status & STATUS_CAPTURE))
701 DEB_D("V4L2_CID_VFLIP while active capture\n");
702 return -EBUSY; 565 return -EBUSY;
703 } 566 vv->vflip = ctrl->val;
704 vv->vflip = c->value;
705 break; 567 break;
568
706 default: 569 default:
707 return -EINVAL; 570 return -EINVAL;
708 } 571 }
709 572
710 if (IS_OVERLAY_ACTIVE(fh) != 0) { 573 if ((vv->video_status & STATUS_OVERLAY) != 0) { /* CHECK: && (vv->video_fh == fh)) */
574 struct saa7146_fh *fh = vv->video_fh;
575
711 saa7146_stop_preview(fh); 576 saa7146_stop_preview(fh);
712 saa7146_start_preview(fh); 577 saa7146_start_preview(fh);
713 } 578 }
@@ -720,6 +585,8 @@ static int vidioc_g_parm(struct file *file, void *fh,
720 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 585 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
721 struct saa7146_vv *vv = dev->vv_data; 586 struct saa7146_vv *vv = dev->vv_data;
722 587
588 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
589 return -EINVAL;
723 parm->parm.capture.readbuffers = 1; 590 parm->parm.capture.readbuffers = 1;
724 v4l2_video_std_frame_period(vv->standard->id, 591 v4l2_video_std_frame_period(vv->standard->id,
725 &parm->parm.capture.timeperframe); 592 &parm->parm.capture.timeperframe);
@@ -787,6 +654,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma
787 } 654 }
788 655
789 f->fmt.pix.field = field; 656 f->fmt.pix.field = field;
657 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
790 if (f->fmt.pix.width > maxw) 658 if (f->fmt.pix.width > maxw)
791 f->fmt.pix.width = maxw; 659 f->fmt.pix.width = maxw;
792 if (f->fmt.pix.height > maxh) 660 if (f->fmt.pix.height > maxh)
@@ -1141,9 +1009,6 @@ const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
1141 .vidioc_dqbuf = vidioc_dqbuf, 1009 .vidioc_dqbuf = vidioc_dqbuf,
1142 .vidioc_g_std = vidioc_g_std, 1010 .vidioc_g_std = vidioc_g_std,
1143 .vidioc_s_std = vidioc_s_std, 1011 .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, 1012 .vidioc_streamon = vidioc_streamon,
1148 .vidioc_streamoff = vidioc_streamoff, 1013 .vidioc_streamoff = vidioc_streamoff,
1149 .vidioc_g_parm = vidioc_g_parm, 1014 .vidioc_g_parm = vidioc_g_parm,
@@ -1338,6 +1203,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file)
1338 fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24; 1203 fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24;
1339 fh->video_fmt.bytesperline = 0; 1204 fh->video_fmt.bytesperline = 0;
1340 fh->video_fmt.field = V4L2_FIELD_ANY; 1205 fh->video_fmt.field = V4L2_FIELD_ANY;
1206 fh->video_fmt.colorspace = V4L2_COLORSPACE_SMPTE170M;
1341 sfmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); 1207 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; 1208 fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8;
1343 1209