aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/ttpci/av7110_v4l.c
diff options
context:
space:
mode:
authorOliver Endriss <o.endriss@gmx.de>2006-01-09 15:21:37 -0500
committerMauro Carvalho Chehab <mchehab@brturbo.com.br>2006-01-09 15:21:37 -0500
commit5b0fa4fff17d944b6a0d4cb35d8e8b5ad0ac3669 (patch)
tree1e31c64267ffabe37c733a00e09b91ba4453651a /drivers/media/dvb/ttpci/av7110_v4l.c
parentd312a46e5340be6a89c662ac483230c0737148c9 (diff)
V4L/DVB (3325): WSS output interface for av7110
- Implemented v4l2 api for sliced vbi data output to pass WSS data from userspace to the av7110 Signed-off-by: Oliver Endriss <o.endriss@gmx.de> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Diffstat (limited to 'drivers/media/dvb/ttpci/av7110_v4l.c')
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c116
1 files changed, 109 insertions, 7 deletions
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index e3296b07caac..94cf38c7e8a8 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -490,6 +490,58 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
490 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index); 490 dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
491 break; 491 break;
492 } 492 }
493 case VIDIOC_G_SLICED_VBI_CAP:
494 {
495 struct v4l2_sliced_vbi_cap *cap = arg;
496 dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
497 memset(cap, 0, sizeof *cap);
498 if (FW_VERSION(av7110->arm_app) >= 0x2623) {
499 cap->service_set = V4L2_SLICED_WSS_625;
500 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
501 }
502 break;
503 }
504 case VIDIOC_G_FMT:
505 {
506 struct v4l2_format *f = arg;
507 dprintk(2, "VIDIOC_G_FMT:\n");
508 if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
509 FW_VERSION(av7110->arm_app) < 0x2623)
510 return -EAGAIN; /* handled by core driver */
511 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
512 if (av7110->wssMode) {
513 f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
514 f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
515 f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
516 }
517 break;
518 }
519 case VIDIOC_S_FMT:
520 {
521 struct v4l2_format *f = arg;
522 dprintk(2, "VIDIOC_S_FMT\n");
523 if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
524 FW_VERSION(av7110->arm_app) < 0x2623)
525 return -EAGAIN; /* handled by core driver */
526 if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
527 f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
528 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
529 /* WSS controlled by firmware */
530 av7110->wssMode = 0;
531 av7110->wssData = 0;
532 return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
533 SetWSSConfig, 1, 0);
534 } else {
535 memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
536 f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
537 f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
538 f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
539 /* WSS controlled by userspace */
540 av7110->wssMode = 1;
541 av7110->wssData = 0;
542 }
543 break;
544 }
493 default: 545 default:
494 printk("no such ioctl\n"); 546 printk("no such ioctl\n");
495 return -ENOIOCTLCMD; 547 return -ENOIOCTLCMD;
@@ -497,6 +549,46 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
497 return 0; 549 return 0;
498} 550}
499 551
552static int av7110_vbi_reset(struct inode *inode, struct file *file)
553{
554 struct saa7146_fh *fh = file->private_data;
555 struct saa7146_dev *dev = fh->dev;
556 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
557
558 dprintk(2, "%s\n", __FUNCTION__);
559 av7110->wssMode = 0;
560 av7110->wssData = 0;
561 if (FW_VERSION(av7110->arm_app) < 0x2623)
562 return 0;
563 else
564 return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
565}
566
567static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
568{
569 struct saa7146_fh *fh = file->private_data;
570 struct saa7146_dev *dev = fh->dev;
571 struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
572 struct v4l2_sliced_vbi_data d;
573 int rc;
574
575 dprintk(2, "%s\n", __FUNCTION__);
576 if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d)
577 return -EINVAL;
578 if (copy_from_user(&d, data, count))
579 return -EFAULT;
580 if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23)
581 return -EINVAL;
582 if (d.id) {
583 av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0];
584 rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig,
585 2, 1, av7110->wssData);
586 } else {
587 av7110->wssData = 0;
588 rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
589 }
590 return (rc < 0) ? rc : count;
591}
500 592
501/**************************************************************************** 593/****************************************************************************
502 * INITIALIZATION 594 * INITIALIZATION
@@ -512,6 +604,9 @@ static struct saa7146_extension_ioctls ioctls[] = {
512 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE }, 604 { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
513 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE }, 605 { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
514 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE }, 606 { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
607 { VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE },
608 { VIDIOC_G_FMT, SAA7146_BEFORE },
609 { VIDIOC_S_FMT, SAA7146_BEFORE },
515 { 0, 0 } 610 { 0, 0 }
516}; 611};
517 612
@@ -692,12 +787,11 @@ int av7110_init_v4l(struct av7110 *av7110)
692 saa7146_vv_release(dev); 787 saa7146_vv_release(dev);
693 return -ENODEV; 788 return -ENODEV;
694 } 789 }
695 if (av7110->analog_tuner_flags) { 790 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
696 if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) { 791 ERR(("cannot register vbi v4l2 device. skipping.\n"));
697 ERR(("cannot register vbi v4l2 device. skipping.\n")); 792 } else {
698 } else { 793 if (av7110->analog_tuner_flags)
699 av7110->analog_tuner_flags |= ANALOG_TUNER_VBI; 794 av7110->analog_tuner_flags |= ANALOG_TUNER_VBI;
700 }
701 } 795 }
702 return 0; 796 return 0;
703} 797}
@@ -778,7 +872,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
778static struct saa7146_ext_vv av7110_vv_data_st = { 872static struct saa7146_ext_vv av7110_vv_data_st = {
779 .inputs = 1, 873 .inputs = 1,
780 .audios = 1, 874 .audios = 1,
781 .capabilities = 0, 875 .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT,
782 .flags = 0, 876 .flags = 0,
783 877
784 .stds = &standard[0], 878 .stds = &standard[0],
@@ -787,12 +881,16 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
787 881
788 .ioctls = &ioctls[0], 882 .ioctls = &ioctls[0],
789 .ioctl = av7110_ioctl, 883 .ioctl = av7110_ioctl,
884
885 .vbi_fops.open = av7110_vbi_reset,
886 .vbi_fops.release = av7110_vbi_reset,
887 .vbi_fops.write = av7110_vbi_write,
790}; 888};
791 889
792static struct saa7146_ext_vv av7110_vv_data_c = { 890static struct saa7146_ext_vv av7110_vv_data_c = {
793 .inputs = 1, 891 .inputs = 1,
794 .audios = 1, 892 .audios = 1,
795 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE, 893 .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT,
796 .flags = SAA7146_USE_PORT_B_FOR_VBI, 894 .flags = SAA7146_USE_PORT_B_FOR_VBI,
797 895
798 .stds = &standard[0], 896 .stds = &standard[0],
@@ -801,5 +899,9 @@ static struct saa7146_ext_vv av7110_vv_data_c = {
801 899
802 .ioctls = &ioctls[0], 900 .ioctls = &ioctls[0],
803 .ioctl = av7110_ioctl, 901 .ioctl = av7110_ioctl,
902
903 .vbi_fops.open = av7110_vbi_reset,
904 .vbi_fops.release = av7110_vbi_reset,
905 .vbi_fops.write = av7110_vbi_write,
804}; 906};
805 907