@@ -490,13 +490,105 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
490
490
dprintk (2 , "VIDIOC_S_AUDIO: %d\n" , a -> index );
491
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
545
default :
494
546
printk ("no such ioctl\n" );
495
547
return - ENOIOCTLCMD ;
496
548
}
497
549
return 0 ;
498
550
}
499
551
552
+ static 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
+
567
+ static 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
594
* INITIALIZATION
@@ -512,6 +604,9 @@ static struct saa7146_extension_ioctls ioctls[] = {
512
604
{ VIDIOC_S_TUNER , SAA7146_EXCLUSIVE },
513
605
{ VIDIOC_G_AUDIO , SAA7146_EXCLUSIVE },
514
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
610
{ 0 , 0 }
516
611
};
517
612
@@ -692,12 +787,11 @@ int av7110_init_v4l(struct av7110 *av7110)
692
787
saa7146_vv_release (dev );
693
788
return - ENODEV ;
694
789
}
695
- if (av7110 -> analog_tuner_flags ) {
696
- if ( saa7146_register_device ( & av7110 -> vbi_dev , dev , "av7110" , VFL_TYPE_VBI )) {
697
- ERR (( "cannot register vbi v4l2 device. skipping.\n" ));
698
- } else {
790
+ if (saa7146_register_device ( & av7110 -> vbi_dev , dev , "av7110" , VFL_TYPE_VBI ) ) {
791
+ ERR (( "cannot register vbi v4l2 device. skipping.\n" ));
792
+ } else {
793
+ if ( av7110 -> analog_tuner_flags )
699
794
av7110 -> analog_tuner_flags |= ANALOG_TUNER_VBI ;
700
- }
701
795
}
702
796
return 0 ;
703
797
}
@@ -778,7 +872,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
778
872
static struct saa7146_ext_vv av7110_vv_data_st = {
779
873
.inputs = 1 ,
780
874
.audios = 1 ,
781
- .capabilities = 0 ,
875
+ .capabilities = V4L2_CAP_SLICED_VBI_OUTPUT ,
782
876
.flags = 0 ,
783
877
784
878
.stds = & standard [0 ],
@@ -787,12 +881,16 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
787
881
788
882
.ioctls = & ioctls [0 ],
789
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
792
890
static struct saa7146_ext_vv av7110_vv_data_c = {
793
891
.inputs = 1 ,
794
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
894
.flags = SAA7146_USE_PORT_B_FOR_VBI ,
797
895
798
896
.stds = & standard [0 ],
@@ -801,5 +899,9 @@ static struct saa7146_ext_vv av7110_vv_data_c = {
801
899
802
900
.ioctls = & ioctls [0 ],
803
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
0 commit comments