aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx88/cx88-video.c')
-rw-r--r--drivers/media/video/cx88/cx88-video.c303
1 files changed, 13 insertions, 290 deletions
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index dc997549b634..c44a079d08c0 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * $Id: cx88-video.c,v 1.70 2005/06/20 03:36:00 mkrufky Exp $ 2 * $Id: cx88-video.c,v 1.79 2005/07/07 14:17:47 mchehab Exp $
3 * 3 *
4 * device driver for Conexant 2388x based TV cards 4 * device driver for Conexant 2388x based TV cards
5 * video4linux video interface 5 * video4linux video interface
@@ -86,13 +86,6 @@ static struct cx88_tvnorm tvnorms[] = {
86 .id = V4L2_STD_NTSC_M_JP, 86 .id = V4L2_STD_NTSC_M_JP,
87 .cxiformat = VideoFormatNTSCJapan, 87 .cxiformat = VideoFormatNTSCJapan,
88 .cxoformat = 0x181f0008, 88 .cxoformat = 0x181f0008,
89#if 0
90 },{
91 .name = "NTSC-4.43",
92 .id = FIXME,
93 .cxiformat = VideoFormatNTSC443,
94 .cxoformat = 0x181f0008,
95#endif
96 },{ 89 },{
97 .name = "PAL-BG", 90 .name = "PAL-BG",
98 .id = V4L2_STD_PAL_BG, 91 .id = V4L2_STD_PAL_BG,
@@ -248,6 +241,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
248 .default_value = 0, 241 .default_value = 0,
249 .type = V4L2_CTRL_TYPE_INTEGER, 242 .type = V4L2_CTRL_TYPE_INTEGER,
250 }, 243 },
244 .off = 0,
251 .reg = MO_CONTR_BRIGHT, 245 .reg = MO_CONTR_BRIGHT,
252 .mask = 0xff00, 246 .mask = 0xff00,
253 .shift = 8, 247 .shift = 8,
@@ -674,231 +668,6 @@ static struct videobuf_queue_ops cx8800_video_qops = {
674 668
675/* ------------------------------------------------------------------ */ 669/* ------------------------------------------------------------------ */
676 670
677#if 0 /* overlay support not finished yet */
678static u32* ov_risc_field(struct cx8800_dev *dev, struct cx8800_fh *fh,
679 u32 *rp, struct btcx_skiplist *skips,
680 u32 sync_line, int skip_even, int skip_odd)
681{
682 int line,maxy,start,end,skip,nskips;
683 u32 ri,ra;
684 u32 addr;
685
686 /* sync instruction */
687 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
688
689 addr = (unsigned long)dev->fbuf.base;
690 addr += dev->fbuf.fmt.bytesperline * fh->win.w.top;
691 addr += (fh->fmt->depth >> 3) * fh->win.w.left;
692
693 /* scan lines */
694 for (maxy = -1, line = 0; line < fh->win.w.height;
695 line++, addr += dev->fbuf.fmt.bytesperline) {
696 if ((line%2) == 0 && skip_even)
697 continue;
698 if ((line%2) == 1 && skip_odd)
699 continue;
700
701 /* calculate clipping */
702 if (line > maxy)
703 btcx_calc_skips(line, fh->win.w.width, &maxy,
704 skips, &nskips, fh->clips, fh->nclips);
705
706 /* write out risc code */
707 for (start = 0, skip = 0; start < fh->win.w.width; start = end) {
708 if (skip >= nskips) {
709 ri = RISC_WRITE;
710 end = fh->win.w.width;
711 } else if (start < skips[skip].start) {
712 ri = RISC_WRITE;
713 end = skips[skip].start;
714 } else {
715 ri = RISC_SKIP;
716 end = skips[skip].end;
717 skip++;
718 }
719 if (RISC_WRITE == ri)
720 ra = addr + (fh->fmt->depth>>3)*start;
721 else
722 ra = 0;
723
724 if (0 == start)
725 ri |= RISC_SOL;
726 if (fh->win.w.width == end)
727 ri |= RISC_EOL;
728 ri |= (fh->fmt->depth>>3) * (end-start);
729
730 *(rp++)=cpu_to_le32(ri);
731 if (0 != ra)
732 *(rp++)=cpu_to_le32(ra);
733 }
734 }
735 kfree(skips);
736 return rp;
737}
738
739static int ov_risc_frame(struct cx8800_dev *dev, struct cx8800_fh *fh,
740 struct cx88_buffer *buf)
741{
742 struct btcx_skiplist *skips;
743 u32 instructions,fields;
744 u32 *rp;
745 int rc;
746
747 /* skip list for window clipping */
748 if (NULL == (skips = kmalloc(sizeof(*skips) * fh->nclips,GFP_KERNEL)))
749 return -ENOMEM;
750
751 fields = 0;
752 if (V4L2_FIELD_HAS_TOP(fh->win.field))
753 fields++;
754 if (V4L2_FIELD_HAS_BOTTOM(fh->win.field))
755 fields++;
756
757 /* estimate risc mem: worst case is (clip+1) * lines instructions
758 + syncs + jump (all 2 dwords) */
759 instructions = (fh->nclips+1) * fh->win.w.height;
760 instructions += 3 + 4;
761 if ((rc = btcx_riscmem_alloc(dev->pci,&buf->risc,instructions*8)) < 0) {
762 kfree(skips);
763 return rc;
764 }
765
766 /* write risc instructions */
767 rp = buf->risc.cpu;
768 switch (fh->win.field) {
769 case V4L2_FIELD_TOP:
770 rp = ov_risc_field(dev, fh, rp, skips, 0, 0, 0);
771 break;
772 case V4L2_FIELD_BOTTOM:
773 rp = ov_risc_field(dev, fh, rp, skips, 0x200, 0, 0);
774 break;
775 case V4L2_FIELD_INTERLACED:
776 rp = ov_risc_field(dev, fh, rp, skips, 0, 0, 1);
777 rp = ov_risc_field(dev, fh, rp, skips, 0x200, 1, 0);
778 break;
779 default:
780 BUG();
781 }
782
783 /* save pointer to jmp instruction address */
784 buf->risc.jmp = rp;
785 kfree(skips);
786 return 0;
787}
788
789static int verify_window(struct cx8800_dev *dev, struct v4l2_window *win)
790{
791 enum v4l2_field field;
792 int maxw, maxh;
793
794 if (NULL == dev->fbuf.base)
795 return -EINVAL;
796 if (win->w.width < 48 || win->w.height < 32)
797 return -EINVAL;
798 if (win->clipcount > 2048)
799 return -EINVAL;
800
801 field = win->field;
802 maxw = norm_maxw(core->tvnorm);
803 maxh = norm_maxh(core->tvnorm);
804
805 if (V4L2_FIELD_ANY == field) {
806 field = (win->w.height > maxh/2)
807 ? V4L2_FIELD_INTERLACED
808 : V4L2_FIELD_TOP;
809 }
810 switch (field) {
811 case V4L2_FIELD_TOP:
812 case V4L2_FIELD_BOTTOM:
813 maxh = maxh / 2;
814 break;
815 case V4L2_FIELD_INTERLACED:
816 break;
817 default:
818 return -EINVAL;
819 }
820
821 win->field = field;
822 if (win->w.width > maxw)
823 win->w.width = maxw;
824 if (win->w.height > maxh)
825 win->w.height = maxh;
826 return 0;
827}
828
829static int setup_window(struct cx8800_dev *dev, struct cx8800_fh *fh,
830 struct v4l2_window *win)
831{
832 struct v4l2_clip *clips = NULL;
833 int n,size,retval = 0;
834
835 if (NULL == fh->fmt)
836 return -EINVAL;
837 retval = verify_window(dev,win);
838 if (0 != retval)
839 return retval;
840
841 /* copy clips -- luckily v4l1 + v4l2 are binary
842 compatible here ...*/
843 n = win->clipcount;
844 size = sizeof(*clips)*(n+4);
845 clips = kmalloc(size,GFP_KERNEL);
846 if (NULL == clips)
847 return -ENOMEM;
848 if (n > 0) {
849 if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) {
850 kfree(clips);
851 return -EFAULT;
852 }
853 }
854
855 /* clip against screen */
856 if (NULL != dev->fbuf.base)
857 n = btcx_screen_clips(dev->fbuf.fmt.width, dev->fbuf.fmt.height,
858 &win->w, clips, n);
859 btcx_sort_clips(clips,n);
860
861 /* 4-byte alignments */
862 switch (fh->fmt->depth) {
863 case 8:
864 case 24:
865 btcx_align(&win->w, clips, n, 3);
866 break;
867 case 16:
868 btcx_align(&win->w, clips, n, 1);
869 break;
870 case 32:
871 /* no alignment fixups needed */
872 break;
873 default:
874 BUG();
875 }
876
877 down(&fh->vidq.lock);
878 if (fh->clips)
879 kfree(fh->clips);
880 fh->clips = clips;
881 fh->nclips = n;
882 fh->win = *win;
883#if 0
884 fh->ov.setup_ok = 1;
885#endif
886
887 /* update overlay if needed */
888 retval = 0;
889#if 0
890 if (check_btres(fh, RESOURCE_OVERLAY)) {
891 struct bttv_buffer *new;
892
893 new = videobuf_alloc(sizeof(*new));
894 bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
895 retval = bttv_switch_overlay(btv,fh,new);
896 }
897#endif
898 up(&fh->vidq.lock);
899 return retval;
900}
901#endif
902 671
903/* ------------------------------------------------------------------ */ 672/* ------------------------------------------------------------------ */
904 673
@@ -1327,9 +1096,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1327 struct cx8800_fh *fh = file->private_data; 1096 struct cx8800_fh *fh = file->private_data;
1328 struct cx8800_dev *dev = fh->dev; 1097 struct cx8800_dev *dev = fh->dev;
1329 struct cx88_core *core = dev->core; 1098 struct cx88_core *core = dev->core;
1330#if 0
1331 unsigned long flags;
1332#endif
1333 int err; 1099 int err;
1334 1100
1335 if (video_debug > 1) 1101 if (video_debug > 1)
@@ -1350,9 +1116,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1350 V4L2_CAP_READWRITE | 1116 V4L2_CAP_READWRITE |
1351 V4L2_CAP_STREAMING | 1117 V4L2_CAP_STREAMING |
1352 V4L2_CAP_VBI_CAPTURE | 1118 V4L2_CAP_VBI_CAPTURE |
1353#if 0
1354 V4L2_CAP_VIDEO_OVERLAY |
1355#endif
1356 0; 1119 0;
1357 if (UNSET != core->tuner_type) 1120 if (UNSET != core->tuner_type)
1358 cap->capabilities |= V4L2_CAP_TUNER; 1121 cap->capabilities |= V4L2_CAP_TUNER;
@@ -1453,36 +1216,6 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1453 } 1216 }
1454 1217
1455 1218
1456#if 0
1457 /* needs review */
1458 case VIDIOC_G_AUDIO:
1459 {
1460 struct v4l2_audio *a = arg;
1461 unsigned int n = a->index;
1462
1463 memset(a,0,sizeof(*a));
1464 a->index = n;
1465 switch (n) {
1466 case 0:
1467 if ((CX88_VMUX_TELEVISION == INPUT(n)->type)
1468 || (CX88_VMUX_CABLE == INPUT(n)->type)) {
1469 strcpy(a->name,"Television");
1470 // FIXME figure out if stereo received and set V4L2_AUDCAP_STEREO.
1471 return 0;
1472 }
1473 break;
1474 case 1:
1475 if (CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q == core->board) {
1476 strcpy(a->name,"Line In");
1477 a->capability = V4L2_AUDCAP_STEREO;
1478 return 0;
1479 }
1480 break;
1481 }
1482 // Audio input not available.
1483 return -EINVAL;
1484 }
1485#endif
1486 1219
1487 /* --- capture ioctls ---------------------------------------- */ 1220 /* --- capture ioctls ---------------------------------------- */
1488 case VIDIOC_ENUM_FMT: 1221 case VIDIOC_ENUM_FMT:
@@ -1592,6 +1325,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1592 1325
1593 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1326 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1594 f->frequency = dev->freq; 1327 f->frequency = dev->freq;
1328
1329 cx88_call_i2c_clients(dev->core,VIDIOC_G_FREQUENCY,f);
1330
1595 return 0; 1331 return 0;
1596 } 1332 }
1597 case VIDIOC_S_FREQUENCY: 1333 case VIDIOC_S_FREQUENCY:
@@ -1846,6 +1582,14 @@ static void cx8800_vid_timeout(unsigned long data)
1846 spin_unlock_irqrestore(&dev->slock,flags); 1582 spin_unlock_irqrestore(&dev->slock,flags);
1847} 1583}
1848 1584
1585static char *cx88_vid_irqs[32] = {
1586 "y_risci1", "u_risci1", "v_risci1", "vbi_risc1",
1587 "y_risci2", "u_risci2", "v_risci2", "vbi_risc2",
1588 "y_oflow", "u_oflow", "v_oflow", "vbi_oflow",
1589 "y_sync", "u_sync", "v_sync", "vbi_sync",
1590 "opc_err", "par_err", "rip_err", "pci_abort",
1591};
1592
1849static void cx8800_vid_irq(struct cx8800_dev *dev) 1593static void cx8800_vid_irq(struct cx8800_dev *dev)
1850{ 1594{
1851 struct cx88_core *core = dev->core; 1595 struct cx88_core *core = dev->core;
@@ -2013,7 +1757,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
2013{ 1757{
2014 struct cx8800_dev *dev; 1758 struct cx8800_dev *dev;
2015 struct cx88_core *core; 1759 struct cx88_core *core;
2016 struct tuner_addr tun_addr;
2017 int err; 1760 int err;
2018 1761
2019 dev = kmalloc(sizeof(*dev),GFP_KERNEL); 1762 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
@@ -2087,22 +1830,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
2087 request_module("tuner"); 1830 request_module("tuner");
2088 if (core->tda9887_conf) 1831 if (core->tda9887_conf)
2089 request_module("tda9887"); 1832 request_module("tda9887");
2090 if (core->radio_type != UNSET) {
2091 tun_addr.v4l2_tuner = V4L2_TUNER_RADIO;
2092 tun_addr.type = core->radio_type;
2093 tun_addr.addr = core->radio_addr;
2094 cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE_ADDR, &tun_addr);
2095 }
2096 if (core->tuner_type != UNSET) {
2097 tun_addr.v4l2_tuner = V4L2_TUNER_ANALOG_TV;
2098 tun_addr.type = core->tuner_type;
2099 tun_addr.addr = core->tuner_addr;
2100 cx88_call_i2c_clients(dev->core,TUNER_SET_TYPE_ADDR, &tun_addr);
2101 }
2102
2103 if (core->tda9887_conf)
2104 cx88_call_i2c_clients(dev->core,TDA9887_SET_CONFIG,&core->tda9887_conf);
2105
2106 /* register v4l devices */ 1833 /* register v4l devices */
2107 dev->video_dev = cx88_vdev_init(core,dev->pci, 1834 dev->video_dev = cx88_vdev_init(core,dev->pci,
2108 &cx8800_video_template,"video"); 1835 &cx8800_video_template,"video");
@@ -2212,10 +1939,8 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
2212 } 1939 }
2213 spin_unlock(&dev->slock); 1940 spin_unlock(&dev->slock);
2214 1941
2215#if 1
2216 /* FIXME -- shutdown device */ 1942 /* FIXME -- shutdown device */
2217 cx88_shutdown(dev->core); 1943 cx88_shutdown(dev->core);
2218#endif
2219 1944
2220 pci_save_state(pci_dev); 1945 pci_save_state(pci_dev);
2221 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) { 1946 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
@@ -2237,10 +1962,8 @@ static int cx8800_resume(struct pci_dev *pci_dev)
2237 pci_set_power_state(pci_dev, PCI_D0); 1962 pci_set_power_state(pci_dev, PCI_D0);
2238 pci_restore_state(pci_dev); 1963 pci_restore_state(pci_dev);
2239 1964
2240#if 1
2241 /* FIXME: re-initialize hardware */ 1965 /* FIXME: re-initialize hardware */
2242 cx88_reset(dev->core); 1966 cx88_reset(dev->core);
2243#endif
2244 1967
2245 /* restart video+vbi capture */ 1968 /* restart video+vbi capture */
2246 spin_lock(&dev->slock); 1969 spin_lock(&dev->slock);