aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@brturbo.com.br>2005-09-09 16:03:41 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 16:57:49 -0400
commite52e98a7eccfb0e7e91630d01690fb11d77db77d (patch)
treed910e743159977ee695c40b795a4b84d43a4dbcb /drivers/media
parent24a70fdce872d70171b1f49dcd1a7c3a4e8396b2 (diff)
[PATCH] v4l: CX88 updates and card additions
- Remove $Id CVS logs for V4L files - add ioctl indirection via cx88_ioctl_hook and cx88_ioctl_translator to cx88-blackbird.c. - declare the indirection hooks from cx88-blackbird.c. - dcprintk macro which uses core instead of dev->core on cx88-video.c. - replace dev->core occurances with core on cx88-video.c. - CodingStyle fixes. - MaxInput replaced by a define. - cx8801 structures moved from cx88.h. - The output_mode needs to be set for the Hauppauge Nova-T DVB-T for versions after 2.6.12. - Corrected GPIO values for cx88 cards #28 & #31 for s-video and composite. - Updated DViCO FusionHDTV5 Gold & added DVB support. - Fixed DViCO FusionHDTV 3 Gold-Q GPIO. - Some clean up in cx88-tvaudio.c - replaced hex values when writing to AUD_CTL to EN_xx for better reading. - Allow select by hand between Mono, Lang1, Lang2 and Stereo for BTSC. - Support for stereo NICAM and BTSC improved. - Broken stereo check removed. - Added support for remote control to Cinergy DVBT-1400. - local var renamed from rc5 to a better name (ircode). - LGDT330X QAM lock bug fixes. - Some reorg: move some bits to struct cx88_core, factor out common ioctl's to cx88_do_ioctl. - Get rid of '//' comments, replace them with #if 0 and /**/. - Minor clean-ups: remove dcprintk and replace all instances of "dev->core" with "core". - Added some registers to control PCI controller at CX2388x chips. - New tuner standby API. - Small mpeg fixes and cleanups for blackbird. - fix mpeg packet size & count - add VIDIOC_QUERYCAP ioctl for the mpeg stream - return more information in struct v4l2_format - fix default window height - small cleanups Signed-off-by: Uli Luckas <luckas@musoft.de> Signed-off-by: Torsten Seeboth <Torsten.Seeboth@t-online.de> Signed-off-by: Nickolay V. Shmyrev <nshmyrev@yandex.ru> Signed-off-by: Michael Krufky <mkrufky@m1k.net> Signed-off-by: Patrick Boettcher <patrick.boettcher@desy.de> Signed-off-by: Catalin Climov <catalin@climov.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c73
-rw-r--r--drivers/media/video/cx88/cx88-cards.c24
-rw-r--r--drivers/media/video/cx88/cx88-core.c21
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c47
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c1
-rw-r--r--drivers/media/video/cx88/cx88-input.c96
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c17
-rw-r--r--drivers/media/video/cx88/cx88-reg.h24
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c742
-rw-r--r--drivers/media/video/cx88/cx88-vbi.c1
-rw-r--r--drivers/media/video/cx88/cx88-video.c388
-rw-r--r--drivers/media/video/cx88/cx88.h39
12 files changed, 874 insertions, 599 deletions
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 4f39688f780..0c0c59e9477 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-blackbird.c,v 1.27 2005/06/03 13:31:50 mchehab Exp $
3 * 2 *
4 * Support for a cx23416 mpeg encoder via cx2388x host port. 3 * Support for a cx23416 mpeg encoder via cx2388x host port.
5 * "blackbird" reference design. 4 * "blackbird" reference design.
@@ -62,7 +61,6 @@ static LIST_HEAD(cx8802_devlist);
62#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF 61#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF
63 62
64/* Firmware API commands */ 63/* Firmware API commands */
65/* #define IVTV_API_STD_TIMEOUT 0x00010000 // 65536, units?? */
66#define IVTV_API_STD_TIMEOUT 500 64#define IVTV_API_STD_TIMEOUT 500
67 65
68#define BLACKBIRD_API_PING 0x80 66#define BLACKBIRD_API_PING 0x80
@@ -696,7 +694,6 @@ static void blackbird_codec_settings(struct cx8802_dev *dev)
696 694
697 /* assign stream type */ 695 /* assign stream type */
698 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM); 696 blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_PROGRAM);
699 /* blackbird_api_cmd(dev, BLACKBIRD_API_SET_STREAM_TYPE, 1, 0, BLACKBIRD_STREAM_TRANSPORT); */
700 697
701 /* assign output port */ 698 /* assign output port */
702 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */ 699 blackbird_api_cmd(dev, BLACKBIRD_API_SET_OUTPUT_PORT, 1, 0, BLACKBIRD_OUTPUT_PORT_STREAMING); /* Host */
@@ -824,7 +821,8 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
824 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, 821 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
825 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 822 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
826 823
827 blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0); /* initialize the video input */ 824 /* initialize the video input */
825 blackbird_api_cmd(dev, BLACKBIRD_API_INIT_VIDEO_INPUT, 0, 0);
828 826
829 msleep(1); 827 msleep(1);
830 828
@@ -833,11 +831,12 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
833 blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE); 831 blackbird_api_cmd(dev, BLACKBIRD_API_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE);
834 msleep(1); 832 msleep(1);
835 833
836 /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); // start capturing to the host interface */ 834 /* start capturing to the host interface */
835 /* blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 0, 0x13); */
837 blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0, 836 blackbird_api_cmd(dev, BLACKBIRD_API_BEGIN_CAPTURE, 2, 0,
838 BLACKBIRD_MPEG_CAPTURE, 837 BLACKBIRD_MPEG_CAPTURE,
839 BLACKBIRD_RAW_BITS_NONE 838 BLACKBIRD_RAW_BITS_NONE
840 ); /* start capturing to the host interface */ 839 );
841 msleep(10); 840 msleep(10);
842 841
843 blackbird_api_cmd(dev, BLACKBIRD_API_REFRESH_INPUT, 0,0); 842 blackbird_api_cmd(dev, BLACKBIRD_API_REFRESH_INPUT, 0,0);
@@ -851,8 +850,8 @@ static int bb_buf_setup(struct videobuf_queue *q,
851{ 850{
852 struct cx8802_fh *fh = q->priv_data; 851 struct cx8802_fh *fh = q->priv_data;
853 852
854 fh->dev->ts_packet_size = 512; 853 fh->dev->ts_packet_size = 188 * 4; /* was: 512 */
855 fh->dev->ts_packet_count = 100; 854 fh->dev->ts_packet_count = 32; /* was: 100 */
856 855
857 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count; 856 *size = fh->dev->ts_packet_size * fh->dev->ts_packet_count;
858 if (0 == *count) 857 if (0 == *count)
@@ -900,12 +899,36 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
900{ 899{
901 struct cx8802_fh *fh = file->private_data; 900 struct cx8802_fh *fh = file->private_data;
902 struct cx8802_dev *dev = fh->dev; 901 struct cx8802_dev *dev = fh->dev;
902 struct cx88_core *core = dev->core;
903 903
904 if (debug > 1) 904 if (debug > 1)
905 cx88_print_ioctl(dev->core->name,cmd); 905 cx88_print_ioctl(core->name,cmd);
906 906
907 switch (cmd) { 907 switch (cmd) {
908 908
909 /* --- capabilities ------------------------------------------ */
910 case VIDIOC_QUERYCAP:
911 {
912 struct v4l2_capability *cap = arg;
913
914 memset(cap,0,sizeof(*cap));
915 strcpy(cap->driver, "cx88_blackbird");
916 strlcpy(cap->card, cx88_boards[core->board].name,sizeof(cap->card));
917 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
918 cap->version = CX88_VERSION_CODE;
919 cap->capabilities =
920 V4L2_CAP_VIDEO_CAPTURE |
921 V4L2_CAP_READWRITE |
922 V4L2_CAP_STREAMING |
923 V4L2_CAP_VBI_CAPTURE |
924 V4L2_CAP_VIDEO_OVERLAY |
925 0;
926 if (UNSET != core->tuner_type)
927 cap->capabilities |= V4L2_CAP_TUNER;
928
929 return 0;
930 }
931
909 /* --- capture ioctls ---------------------------------------- */ 932 /* --- capture ioctls ---------------------------------------- */
910 case VIDIOC_ENUM_FMT: 933 case VIDIOC_ENUM_FMT:
911 { 934 {
@@ -935,7 +958,11 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
935 f->fmt.pix.width = dev->width; 958 f->fmt.pix.width = dev->width;
936 f->fmt.pix.height = dev->height; 959 f->fmt.pix.height = dev->height;
937 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; 960 f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
938 f->fmt.pix.sizeimage = 1024 * 512 /* FIXME: BUFFER_SIZE */; 961 f->fmt.pix.field = V4L2_FIELD_NONE;
962 f->fmt.pix.bytesperline = 0;
963 f->fmt.pix.sizeimage = 188 * 4 * 1024; /* 1024 * 512 */ /* FIXME: BUFFER_SIZE */;
964 f->fmt.pix.colorspace = 0;
965 return 0;
939 } 966 }
940 967
941 /* --- streaming capture ------------------------------------- */ 968 /* --- streaming capture ------------------------------------- */
@@ -959,15 +986,25 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file,
959 return videobuf_streamoff(&fh->mpegq); 986 return videobuf_streamoff(&fh->mpegq);
960 987
961 default: 988 default:
962 return -EINVAL; 989 return cx88_do_ioctl( inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook );
963 } 990 }
964 return 0; 991 return 0;
965} 992}
966 993
994int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
995 unsigned int cmd, void *arg);
996unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
997
998static unsigned int mpeg_translate_ioctl(unsigned int cmd)
999{
1000 return cmd;
1001}
1002
967static int mpeg_ioctl(struct inode *inode, struct file *file, 1003static int mpeg_ioctl(struct inode *inode, struct file *file,
968 unsigned int cmd, unsigned long arg) 1004 unsigned int cmd, unsigned long arg)
969{ 1005{
970 return video_usercopy(inode, file, cmd, arg, mpeg_do_ioctl); 1006 cmd = cx88_ioctl_translator( cmd );
1007 return video_usercopy(inode, file, cmd, arg, cx88_ioctl_hook);
971} 1008}
972 1009
973static int mpeg_open(struct inode *inode, struct file *file) 1010static int mpeg_open(struct inode *inode, struct file *file)
@@ -1135,7 +1172,7 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1135 dev->pci = pci_dev; 1172 dev->pci = pci_dev;
1136 dev->core = core; 1173 dev->core = core;
1137 dev->width = 720; 1174 dev->width = 720;
1138 dev->height = 480; 1175 dev->height = 576;
1139 1176
1140 err = cx8802_init_common(dev); 1177 err = cx8802_init_common(dev);
1141 if (0 != err) 1178 if (0 != err)
@@ -1148,6 +1185,9 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1148 1185
1149 list_add_tail(&dev->devlist,&cx8802_devlist); 1186 list_add_tail(&dev->devlist,&cx8802_devlist);
1150 blackbird_register_video(dev); 1187 blackbird_register_video(dev);
1188
1189 /* initial device configuration: needed ? */
1190
1151 return 0; 1191 return 0;
1152 1192
1153 fail_free: 1193 fail_free:
@@ -1202,6 +1242,8 @@ static int blackbird_init(void)
1202 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", 1242 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
1203 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); 1243 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1204#endif 1244#endif
1245 cx88_ioctl_hook = mpeg_do_ioctl;
1246 cx88_ioctl_translator = mpeg_translate_ioctl;
1205 return pci_register_driver(&blackbird_pci_driver); 1247 return pci_register_driver(&blackbird_pci_driver);
1206} 1248}
1207 1249
@@ -1213,6 +1255,9 @@ static void blackbird_fini(void)
1213module_init(blackbird_init); 1255module_init(blackbird_init);
1214module_exit(blackbird_fini); 1256module_exit(blackbird_fini);
1215 1257
1258EXPORT_SYMBOL(cx88_ioctl_hook);
1259EXPORT_SYMBOL(cx88_ioctl_translator);
1260
1216/* ----------------------------------------------------------- */ 1261/* ----------------------------------------------------------- */
1217/* 1262/*
1218 * Local variables: 1263 * Local variables:
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index ebf02a7f81e..92623231db7 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-cards.c,v 1.90 2005/07/28 02:47:42 mkrufky Exp $
3 * 2 *
4 * device driver for Conexant 2388x based TV cards 3 * device driver for Conexant 2388x based TV cards
5 * card-specific stuff. 4 * card-specific stuff.
@@ -499,9 +498,6 @@ struct cx88_board cx88_boards[] = {
499 .input = {{ 498 .input = {{
500 .type = CX88_VMUX_DVB, 499 .type = CX88_VMUX_DVB,
501 .vmux = 0, 500 .vmux = 0,
502 },{
503 .type = CX88_VMUX_SVIDEO,
504 .vmux = 2,
505 }}, 501 }},
506 .dvb = 1, 502 .dvb = 1,
507 }, 503 },
@@ -614,12 +610,12 @@ struct cx88_board cx88_boards[] = {
614 .input = {{ 610 .input = {{
615 .type = CX88_VMUX_TELEVISION, 611 .type = CX88_VMUX_TELEVISION,
616 .vmux = 0, 612 .vmux = 0,
617 .gpio0 = 0xed12, // internal decoder 613 .gpio0 = 0xed12, /* internal decoder */
618 .gpio2 = 0x00ff, 614 .gpio2 = 0x00ff,
619 },{ 615 },{
620 .type = CX88_VMUX_DEBUG, 616 .type = CX88_VMUX_DEBUG,
621 .vmux = 0, 617 .vmux = 0,
622 .gpio0 = 0xff01, // mono from tuner chip 618 .gpio0 = 0xff01, /* mono from tuner chip */
623 },{ 619 },{
624 .type = CX88_VMUX_COMPOSITE1, 620 .type = CX88_VMUX_COMPOSITE1,
625 .vmux = 1, 621 .vmux = 1,
@@ -715,19 +711,18 @@ struct cx88_board cx88_boards[] = {
715 .radio_type = UNSET, 711 .radio_type = UNSET,
716 .tuner_addr = ADDR_UNSET, 712 .tuner_addr = ADDR_UNSET,
717 .radio_addr = ADDR_UNSET, 713 .radio_addr = ADDR_UNSET,
718 /* See DViCO FusionHDTV 3 Gold-Q for GPIO documentation. */
719 .input = {{ 714 .input = {{
720 .type = CX88_VMUX_TELEVISION, 715 .type = CX88_VMUX_TELEVISION,
721 .vmux = 0, 716 .vmux = 0,
722 .gpio0 = 0x0f0d, 717 .gpio0 = 0x97ed,
723 },{ 718 },{
724 .type = CX88_VMUX_COMPOSITE1, 719 .type = CX88_VMUX_COMPOSITE1,
725 .vmux = 1, 720 .vmux = 1,
726 .gpio0 = 0x0f00, 721 .gpio0 = 0x97e9,
727 },{ 722 },{
728 .type = CX88_VMUX_SVIDEO, 723 .type = CX88_VMUX_SVIDEO,
729 .vmux = 2, 724 .vmux = 2,
730 .gpio0 = 0x0f00, 725 .gpio0 = 0x97e9,
731 }}, 726 }},
732 .dvb = 1, 727 .dvb = 1,
733 }, 728 },
@@ -765,20 +760,21 @@ struct cx88_board cx88_boards[] = {
765 .radio_type = UNSET, 760 .radio_type = UNSET,
766 .tuner_addr = ADDR_UNSET, 761 .tuner_addr = ADDR_UNSET,
767 .radio_addr = ADDR_UNSET, 762 .radio_addr = ADDR_UNSET,
768 /* See DViCO FusionHDTV 3 Gold-Q for GPIO documentation. */ 763 .tda9887_conf = TDA9887_PRESENT,
769 .input = {{ 764 .input = {{
770 .type = CX88_VMUX_TELEVISION, 765 .type = CX88_VMUX_TELEVISION,
771 .vmux = 0, 766 .vmux = 0,
772 .gpio0 = 0x0f0d, 767 .gpio0 = 0x87fd,
773 },{ 768 },{
774 .type = CX88_VMUX_COMPOSITE1, 769 .type = CX88_VMUX_COMPOSITE1,
775 .vmux = 1, 770 .vmux = 1,
776 .gpio0 = 0x0f00, 771 .gpio0 = 0x87f9,
777 },{ 772 },{
778 .type = CX88_VMUX_SVIDEO, 773 .type = CX88_VMUX_SVIDEO,
779 .vmux = 2, 774 .vmux = 2,
780 .gpio0 = 0x0f00, 775 .gpio0 = 0x87f9,
781 }}, 776 }},
777 .dvb = 1,
782 }, 778 },
783}; 779};
784const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 780const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index 5e868f5cd0c..dc5c5c1f346 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-core.c,v 1.33 2005/07/07 14:17:47 mchehab Exp $
3 * 2 *
4 * device driver for Conexant 2388x based TV cards 3 * device driver for Conexant 2388x based TV cards
5 * driver core 4 * driver core
@@ -876,7 +875,7 @@ static int set_tvaudio(struct cx88_core *core)
876 875
877 cx_andor(MO_AFECFG_IO, 0x1f, 0x0); 876 cx_andor(MO_AFECFG_IO, 0x1f, 0x0);
878 cx88_set_tvaudio(core); 877 cx88_set_tvaudio(core);
879 // cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); 878 /* cx88_set_stereo(dev,V4L2_TUNER_MODE_STEREO); */
880 879
881 cx_write(MO_AUDD_LNGTH, 128); /* fifo size */ 880 cx_write(MO_AUDD_LNGTH, 128); /* fifo size */
882 cx_write(MO_AUDR_LNGTH, 128); /* fifo size */ 881 cx_write(MO_AUDR_LNGTH, 128); /* fifo size */
@@ -1087,10 +1086,17 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1087 core->pci_bus = pci->bus->number; 1086 core->pci_bus = pci->bus->number;
1088 core->pci_slot = PCI_SLOT(pci->devfn); 1087 core->pci_slot = PCI_SLOT(pci->devfn);
1089 core->pci_irqmask = 0x00fc00; 1088 core->pci_irqmask = 0x00fc00;
1089 init_MUTEX(&core->lock);
1090 1090
1091 core->nr = cx88_devcount++; 1091 core->nr = cx88_devcount++;
1092 sprintf(core->name,"cx88[%d]",core->nr); 1092 sprintf(core->name,"cx88[%d]",core->nr);
1093 if (0 != get_ressources(core,pci)) { 1093 if (0 != get_ressources(core,pci)) {
1094 printk(KERN_ERR "CORE %s No more PCI ressources for "
1095 "subsystem: %04x:%04x, board: %s\n",
1096 core->name,pci->subsystem_vendor,
1097 pci->subsystem_device,
1098 cx88_boards[core->board].name);
1099
1094 cx88_devcount--; 1100 cx88_devcount--;
1095 goto fail_free; 1101 goto fail_free;
1096 } 1102 }
@@ -1114,11 +1120,11 @@ struct cx88_core* cx88_core_get(struct pci_dev *pci)
1114 core->board = CX88_BOARD_UNKNOWN; 1120 core->board = CX88_BOARD_UNKNOWN;
1115 cx88_card_list(core,pci); 1121 cx88_card_list(core,pci);
1116 } 1122 }
1117 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", 1123 printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1118 core->name,pci->subsystem_vendor, 1124 core->name,pci->subsystem_vendor,
1119 pci->subsystem_device,cx88_boards[core->board].name, 1125 pci->subsystem_device,cx88_boards[core->board].name,
1120 core->board, card[core->nr] == core->board ? 1126 core->board, card[core->nr] == core->board ?
1121 "insmod option" : "autodetected"); 1127 "insmod option" : "autodetected");
1122 1128
1123 core->tuner_type = tuner[core->nr]; 1129 core->tuner_type = tuner[core->nr];
1124 core->radio_type = radio[core->nr]; 1130 core->radio_type = radio[core->nr];
@@ -1202,4 +1208,5 @@ EXPORT_SYMBOL(cx88_core_put);
1202 * Local variables: 1208 * Local variables:
1203 * c-basic-offset: 8 1209 * c-basic-offset: 8
1204 * End: 1210 * End:
1211 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
1205 */ 1212 */
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 78d223257a6..cc71cafc2cb 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-dvb.c,v 1.58 2005/08/07 09:24:08 mkrufky Exp $
3 * 2 *
4 * device driver for Conexant 2388x based TV cards 3 * device driver for Conexant 2388x based TV cards
5 * MPEG Transport Stream (DVB) routines 4 * MPEG Transport Stream (DVB) routines
@@ -31,6 +30,7 @@
31#include <linux/suspend.h> 30#include <linux/suspend.h>
32#include <linux/config.h> 31#include <linux/config.h>
33 32
33
34#include "cx88.h" 34#include "cx88.h"
35#include "dvb-pll.h" 35#include "dvb-pll.h"
36 36
@@ -210,16 +210,26 @@ static struct or51132_config pchdtv_hd3000 = {
210static int lgdt330x_pll_set(struct dvb_frontend* fe, 210static int lgdt330x_pll_set(struct dvb_frontend* fe,
211 struct dvb_frontend_parameters* params) 211 struct dvb_frontend_parameters* params)
212{ 212{
213 /* FIXME make this routine use the tuner-simple code.
214 * It could probably be shared with a number of ATSC
215 * frontends. Many share the same tuner with analog TV. */
216
213 struct cx8802_dev *dev= fe->dvb->priv; 217 struct cx8802_dev *dev= fe->dvb->priv;
218 struct cx88_core *core = dev->core;
214 u8 buf[4]; 219 u8 buf[4];
215 struct i2c_msg msg = 220 struct i2c_msg msg =
216 { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 }; 221 { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 };
217 int err; 222 int err;
218 223
219 dvb_pll_configure(dev->core->pll_desc, buf, params->frequency, 0); 224 /* Put the analog decoder in standby to keep it quiet */
225 if (core->tda9887_conf) {
226 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
227 }
228
229 dvb_pll_configure(core->pll_desc, buf, params->frequency, 0);
220 dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", 230 dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
221 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); 231 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
222 if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { 232 if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) {
223 printk(KERN_WARNING "cx88-dvb: %s error " 233 printk(KERN_WARNING "cx88-dvb: %s error "
224 "(addr %02x <- %02x, err = %i)\n", 234 "(addr %02x <- %02x, err = %i)\n",
225 __FUNCTION__, buf[0], buf[1], err); 235 __FUNCTION__, buf[0], buf[1], err);
@@ -228,6 +238,13 @@ static int lgdt330x_pll_set(struct dvb_frontend* fe,
228 else 238 else
229 return -EREMOTEIO; 239 return -EREMOTEIO;
230 } 240 }
241 if (core->tuner_type == TUNER_LG_TDVS_H062F) {
242 /* Set the Auxiliary Byte. */
243 buf[2] &= ~0x20;
244 buf[2] |= 0x18;
245 buf[3] = 0x50;
246 i2c_transfer(&core->i2c_adap, &msg, 1);
247 }
231 return 0; 248 return 0;
232} 249}
233 250
@@ -261,6 +278,14 @@ static struct lgdt330x_config fusionhdtv_3_gold = {
261 .pll_set = lgdt330x_pll_set, 278 .pll_set = lgdt330x_pll_set,
262 .set_ts_params = lgdt330x_set_ts_param, 279 .set_ts_params = lgdt330x_set_ts_param,
263}; 280};
281
282static struct lgdt330x_config fusionhdtv_5_gold = {
283 .demod_address = 0x0e,
284 .demod_chip = LGDT3303,
285 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
286 .pll_set = lgdt330x_pll_set,
287 .set_ts_params = lgdt330x_set_ts_param,
288};
264#endif 289#endif
265 290
266static int dvb_register(struct cx8802_dev *dev) 291static int dvb_register(struct cx8802_dev *dev)
@@ -346,6 +371,22 @@ static int dvb_register(struct cx8802_dev *dev)
346 &dev->core->i2c_adap); 371 &dev->core->i2c_adap);
347 } 372 }
348 break; 373 break;
374 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
375 dev->ts_gen_cntrl = 0x08;
376 {
377 /* Do a hardware reset of chip before using it. */
378 struct cx88_core *core = dev->core;
379
380 cx_clear(MO_GP0_IO, 1);
381 mdelay(100);
382 cx_set(MO_GP0_IO, 1);
383 mdelay(200);
384 dev->core->pll_addr = 0x61;
385 dev->core->pll_desc = &dvb_pll_tdvs_tua6034;
386 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_5_gold,
387 &dev->core->i2c_adap);
388 }
389 break;
349#endif 390#endif
350 default: 391 default:
351 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 392 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index 7f598039e02..761cebd40db 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: cx88-i2c.c,v 1.30 2005/07/25 05:10:13 mkrufky Exp $
3 2
4 cx88-i2c.c -- all the i2c code is here 3 cx88-i2c.c -- all the i2c code is here
5 4
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 21488779819..d7980c51478 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-input.c,v 1.15 2005/07/07 13:58:38 mchehab Exp $
3 * 2 *
4 * Device driver for GPIO attached remote control interfaces 3 * Device driver for GPIO attached remote control interfaces
5 * on Conexant 2388x based TV/DVB cards. 4 * on Conexant 2388x based TV/DVB cards.
@@ -212,6 +211,53 @@ static IR_KEYTAB_TYPE ir_codes_msi_tvanywhere[IR_KEYTAB_SIZE] = {
212 211
213/* ---------------------------------------------------------------------- */ 212/* ---------------------------------------------------------------------- */
214 213
214/* Cinergy 1400 DVB-T */
215static IR_KEYTAB_TYPE ir_codes_cinergy_1400[IR_KEYTAB_SIZE] = {
216 [0x01] = KEY_POWER,
217 [0x02] = KEY_1,
218 [0x03] = KEY_2,
219 [0x04] = KEY_3,
220 [0x05] = KEY_4,
221 [0x06] = KEY_5,
222 [0x07] = KEY_6,
223 [0x08] = KEY_7,
224 [0x09] = KEY_8,
225 [0x0a] = KEY_9,
226 [0x0c] = KEY_0,
227
228 [0x0b] = KEY_VIDEO,
229 [0x0d] = KEY_REFRESH,
230 [0x0e] = KEY_SELECT,
231 [0x0f] = KEY_EPG,
232 [0x10] = KEY_UP,
233 [0x11] = KEY_LEFT,
234 [0x12] = KEY_OK,
235 [0x13] = KEY_RIGHT,
236 [0x14] = KEY_DOWN,
237 [0x15] = KEY_TEXT,
238 [0x16] = KEY_INFO,
239
240 [0x17] = KEY_RED,
241 [0x18] = KEY_GREEN,
242 [0x19] = KEY_YELLOW,
243 [0x1a] = KEY_BLUE,
244
245 [0x1b] = KEY_CHANNELUP,
246 [0x1c] = KEY_VOLUMEUP,
247 [0x1d] = KEY_MUTE,
248 [0x1e] = KEY_VOLUMEDOWN,
249 [0x1f] = KEY_CHANNELDOWN,
250
251 [0x40] = KEY_PAUSE,
252 [0x4c] = KEY_PLAY,
253 [0x58] = KEY_RECORD,
254 [0x54] = KEY_PREVIOUS,
255 [0x48] = KEY_STOP,
256 [0x5c] = KEY_NEXT,
257};
258
259/* ---------------------------------------------------------------------- */
260
215struct cx88_IR { 261struct cx88_IR {
216 struct cx88_core *core; 262 struct cx88_core *core;
217 struct input_dev input; 263 struct input_dev input;
@@ -241,7 +287,7 @@ module_param(ir_debug, int, 0644); /* debug level [IR] */
241MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); 287MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
242 288
243#define ir_dprintk(fmt, arg...) if (ir_debug) \ 289#define ir_dprintk(fmt, arg...) if (ir_debug) \
244 printk(KERN_DEBUG "%s IR: " fmt , ir->core->name, ## arg) 290 printk(KERN_DEBUG "%s IR: " fmt , ir->core->name , ##arg)
245 291
246/* ---------------------------------------------------------------------- */ 292/* ---------------------------------------------------------------------- */
247 293
@@ -329,6 +375,11 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
329 ir->mask_keyup = 0x60; 375 ir->mask_keyup = 0x60;
330 ir->polling = 50; /* ms */ 376 ir->polling = 50; /* ms */
331 break; 377 break;
378 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
379 ir_codes = ir_codes_cinergy_1400;
380 ir_type = IR_TYPE_PD;
381 ir->sampling = 1;
382 break;
332 case CX88_BOARD_HAUPPAUGE: 383 case CX88_BOARD_HAUPPAUGE:
333 case CX88_BOARD_HAUPPAUGE_DVB_T1: 384 case CX88_BOARD_HAUPPAUGE_DVB_T1:
334 ir_codes = ir_codes_hauppauge_new; 385 ir_codes = ir_codes_hauppauge_new;
@@ -445,7 +496,7 @@ int cx88_ir_fini(struct cx88_core *core)
445void cx88_ir_irq(struct cx88_core *core) 496void cx88_ir_irq(struct cx88_core *core)
446{ 497{
447 struct cx88_IR *ir = core->ir; 498 struct cx88_IR *ir = core->ir;
448 u32 samples, rc5; 499 u32 samples, ircode;
449 int i; 500 int i;
450 501
451 if (NULL == ir) 502 if (NULL == ir)
@@ -477,13 +528,44 @@ void cx88_ir_irq(struct cx88_core *core)
477 528
478 /* decode it */ 529 /* decode it */
479 switch (core->board) { 530 switch (core->board) {
531 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
532 ircode = ir_decode_pulsedistance(ir->samples, ir->scount, 1, 4);
533
534 if (ircode == 0xffffffff) { /* decoding error */
535 ir_dprintk("pulse distance decoding error\n");
536 break;
537 }
538
539 ir_dprintk("pulse distance decoded: %x\n", ircode);
540
541 if (ircode == 0) { /* key still pressed */
542 ir_dprintk("pulse distance decoded repeat code\n");
543 ir->release = jiffies + msecs_to_jiffies(120);
544 break;
545 }
546
547 if ((ircode & 0xffff) != 0xeb04) { /* wrong address */
548 ir_dprintk("pulse distance decoded wrong address\n");
549 break;
550 }
551
552 if (((~ircode >> 24) & 0xff) != ((ircode >> 16) & 0xff)) { /* wrong checksum */
553 ir_dprintk("pulse distance decoded wrong check sum\n");
554 break;
555 }
556
557 ir_dprintk("Key Code: %x\n", (ircode >> 16) & 0x7f);
558
559 ir_input_keydown(&ir->input, &ir->ir, (ircode >> 16) & 0x7f, (ircode >> 16) & 0xff);
560 ir->release = jiffies + msecs_to_jiffies(120);
561 break;
480 case CX88_BOARD_HAUPPAUGE: 562 case CX88_BOARD_HAUPPAUGE:
481 case CX88_BOARD_HAUPPAUGE_DVB_T1: 563 case CX88_BOARD_HAUPPAUGE_DVB_T1:
482 rc5 = ir_decode_biphase(ir->samples, ir->scount, 5, 7); 564 ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
483 ir_dprintk("biphase decoded: %x\n", rc5); 565 ir_dprintk("biphase decoded: %x\n", ircode);
484 if ((rc5 & 0xfffff000) != 0x3000) 566 if ((ircode & 0xfffff000) != 0x3000)
485 break; 567 break;
486 ir_input_keydown(&ir->input, &ir->ir, rc5 & 0x3f, rc5); 568 ir_input_keydown(&ir->input, &ir->ir, ircode & 0x3f, ircode);
487 ir->release = jiffies + msecs_to_jiffies(120); 569 ir->release = jiffies + msecs_to_jiffies(120);
488 break; 570 break;
489 } 571 }
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index fe2767c0ff9..6d0d15c3a1c 100644
--- a/drivers/media/video/cx88/cx88-mpeg.c
+++ b/drivers/media/video/cx88/cx88-mpeg.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-mpeg.c,v 1.31 2005/07/07 14:17:47 mchehab Exp $
3 * 2 *
4 * Support for the mpeg transport stream transfers 3 * Support for the mpeg transport stream transfers
5 * PCI function #2 of the cx2388x. 4 * PCI function #2 of the cx2388x.
@@ -73,11 +72,15 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
73 udelay(100); 72 udelay(100);
74 cx_write(MO_PINMUX_IO, 0x00); 73 cx_write(MO_PINMUX_IO, 0x00);
75 cx_write(TS_HW_SOP_CNTRL,0x47<<16|188<<4|0x01); 74 cx_write(TS_HW_SOP_CNTRL,0x47<<16|188<<4|0x01);
76 if ((core->board == CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q) || 75 switch (core->board) {
77 (core->board == CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T)) { 76 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
77 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
78 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
78 cx_write(TS_SOP_STAT, 1<<13); 79 cx_write(TS_SOP_STAT, 1<<13);
79 } else { 80 break;
81 default:
80 cx_write(TS_SOP_STAT, 0x00); 82 cx_write(TS_SOP_STAT, 0x00);
83 break;
81 } 84 }
82 cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl); 85 cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl);
83 udelay(100); 86 udelay(100);
@@ -86,12 +89,10 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
86 if (cx88_boards[core->board].blackbird) { 89 if (cx88_boards[core->board].blackbird) {
87 cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */ 90 cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */
88 91
89 // cx_write(TS_F2_CMD_STAT_MM, 0x2900106); /* F2_CMD_STAT_MM defaults + master + memory space */
90 cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */ 92 cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */
91 udelay(100); 93 udelay(100);
92 94
93 cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */ 95 cx_write(TS_HW_SOP_CNTRL, 0x408); /* mpeg start byte */
94 //cx_write(TS_HW_SOP_CNTRL, 0x2F0BC0); /* mpeg start byte ts: 0x2F0BC0 ? */
95 cx_write(TS_VALERR_CNTRL, 0x2000); 96 cx_write(TS_VALERR_CNTRL, 0x2000);
96 97
97 cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */ 98 cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */
@@ -106,7 +107,6 @@ static int cx8802_start_dma(struct cx8802_dev *dev,
106 dprintk( 0, "setting the interrupt mask\n" ); 107 dprintk( 0, "setting the interrupt mask\n" );
107 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); 108 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04);
108 cx_set(MO_TS_INTMSK, 0x1f0011); 109 cx_set(MO_TS_INTMSK, 0x1f0011);
109 //cx_write(MO_TS_INTMSK, 0x0f0011);
110 110
111 /* start dma */ 111 /* start dma */
112 cx_set(MO_DEV_CNTRL2, (1<<5)); 112 cx_set(MO_DEV_CNTRL2, (1<<5));
@@ -206,7 +206,6 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
206 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); 206 mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT);
207 dprintk(0,"[%p/%d] %s - first active\n", 207 dprintk(0,"[%p/%d] %s - first active\n",
208 buf, buf->vb.i, __FUNCTION__); 208 buf, buf->vb.i, __FUNCTION__);
209 //udelay(100);
210 209
211 } else { 210 } else {
212 dprintk( 1, "queue is not empty - append to active\n" ); 211 dprintk( 1, "queue is not empty - append to active\n" );
@@ -217,7 +216,6 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf)
217 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); 216 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
218 dprintk( 1, "[%p/%d] %s - append to active\n", 217 dprintk( 1, "[%p/%d] %s - append to active\n",
219 buf, buf->vb.i, __FUNCTION__); 218 buf, buf->vb.i, __FUNCTION__);
220 //udelay(100);
221 } 219 }
222} 220}
223 221
@@ -387,7 +385,6 @@ int cx8802_init_common(struct cx8802_dev *dev)
387 dev->pci_lat,pci_resource_start(dev->pci,0)); 385 dev->pci_lat,pci_resource_start(dev->pci,0));
388 386
389 /* initialize driver struct */ 387 /* initialize driver struct */
390 init_MUTEX(&dev->lock);
391 spin_lock_init(&dev->slock); 388 spin_lock_init(&dev->slock);
392 389
393 /* init dma queue */ 390 /* init dma queue */
diff --git a/drivers/media/video/cx88/cx88-reg.h b/drivers/media/video/cx88/cx88-reg.h
index 37f82662d26..0a3a62fc9bb 100644
--- a/drivers/media/video/cx88/cx88-reg.h
+++ b/drivers/media/video/cx88/cx88-reg.h
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: cx88-reg.h,v 1.8 2005/07/07 13:58:38 mchehab Exp $
3 2
4 cx88x-hw.h - CX2388x register offsets 3 cx88x-hw.h - CX2388x register offsets
5 4
@@ -40,6 +39,29 @@
40#define CX88X_EN_TBFX 0x02 39#define CX88X_EN_TBFX 0x02
41#define CX88X_EN_VSFX 0x04 40#define CX88X_EN_VSFX 0x04
42 41
42/* ---------------------------------------------------------------------- */
43/* PCI controller registers */
44
45/* Command and Status Register */
46#define F0_CMD_STAT_MM 0x2f0004
47#define F1_CMD_STAT_MM 0x2f0104
48#define F2_CMD_STAT_MM 0x2f0204
49#define F3_CMD_STAT_MM 0x2f0304
50#define F4_CMD_STAT_MM 0x2f0404
51
52/* Device Control #1 */
53#define F0_DEV_CNTRL1_MM 0x2f0040
54#define F1_DEV_CNTRL1_MM 0x2f0140
55#define F2_DEV_CNTRL1_MM 0x2f0240
56#define F3_DEV_CNTRL1_MM 0x2f0340
57#define F4_DEV_CNTRL1_MM 0x2f0440
58
59/* Device Control #1 */
60#define F0_BAR0_MM 0x2f0010
61#define F1_BAR0_MM 0x2f0110
62#define F2_BAR0_MM 0x2f0210
63#define F3_BAR0_MM 0x2f0310
64#define F4_BAR0_MM 0x2f0410
43 65
44/* ---------------------------------------------------------------------- */ 66/* ---------------------------------------------------------------------- */
45/* DMA Controller registers */ 67/* DMA Controller registers */
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 91207f10bae..2765acee028 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -1,5 +1,4 @@
1/* 1/*
2 $Id: cx88-tvaudio.c,v 1.37 2005/07/07 13:58:38 mchehab Exp $
3 2
4 cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver 3 cx88x-audio.c - Conexant CX23880/23881 audio downstream driver driver
5 4
@@ -121,25 +120,19 @@ static void set_audio_registers(struct cx88_core *core,
121} 120}
122 121
123static void set_audio_start(struct cx88_core *core, 122static void set_audio_start(struct cx88_core *core,
124 u32 mode, u32 ctl) 123 u32 mode)
125{ 124{
126 // mute 125 // mute
127 cx_write(AUD_VOL_CTL, (1 << 6)); 126 cx_write(AUD_VOL_CTL, (1 << 6));
128 127
129 // increase level of input by 12dB
130// cx_write(AUD_AFE_12DB_EN, 0x0001);
131 cx_write(AUD_AFE_12DB_EN, 0x0000);
132
133 // start programming 128 // start programming
134 cx_write(AUD_CTL, 0x0000); 129 cx_write(AUD_CTL, 0x0000);
135 cx_write(AUD_INIT, mode); 130 cx_write(AUD_INIT, mode);
136 cx_write(AUD_INIT_LD, 0x0001); 131 cx_write(AUD_INIT_LD, 0x0001);
137 cx_write(AUD_SOFT_RESET, 0x0001); 132 cx_write(AUD_SOFT_RESET, 0x0001);
138
139 cx_write(AUD_CTL, ctl);
140} 133}
141 134
142static void set_audio_finish(struct cx88_core *core) 135static void set_audio_finish(struct cx88_core *core, u32 ctl)
143{ 136{
144 u32 volume; 137 u32 volume;
145 138
@@ -154,25 +147,25 @@ static void set_audio_finish(struct cx88_core *core)
154 cx_write(AUD_I2SOUTPUTCNTL, 1); 147 cx_write(AUD_I2SOUTPUTCNTL, 1);
155 cx_write(AUD_I2SCNTL, 0); 148 cx_write(AUD_I2SCNTL, 0);
156 //cx_write(AUD_APB_IN_RATE_ADJ, 0); 149 //cx_write(AUD_APB_IN_RATE_ADJ, 0);
150 } else {
151 ctl |= EN_DAC_ENABLE;
152 cx_write(AUD_CTL, ctl);
157 } 153 }
158 154
159 // finish programming 155 /* finish programming */
160 cx_write(AUD_SOFT_RESET, 0x0000); 156 cx_write(AUD_SOFT_RESET, 0x0000);
161 157
162 // start audio processing 158 /* unmute */
163 cx_set(AUD_CTL, EN_DAC_ENABLE);
164
165 // unmute
166 volume = cx_sread(SHADOW_AUD_VOL_CTL); 159 volume = cx_sread(SHADOW_AUD_VOL_CTL);
167 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume); 160 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, volume);
168} 161}
169 162
170/* ----------------------------------------------------------- */ 163/* ----------------------------------------------------------- */
171 164
172static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap) 165static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap, u32 mode)
173{ 166{
174 static const struct rlist btsc[] = { 167 static const struct rlist btsc[] = {
175 /* from dscaler */ 168 { AUD_AFE_12DB_EN, 0x00000001 },
176 { AUD_OUT1_SEL, 0x00000013 }, 169 { AUD_OUT1_SEL, 0x00000013 },
177 { AUD_OUT1_SHIFT, 0x00000000 }, 170 { AUD_OUT1_SHIFT, 0x00000000 },
178 { AUD_POLY0_DDS_CONSTANT, 0x0012010c }, 171 { AUD_POLY0_DDS_CONSTANT, 0x0012010c },
@@ -206,9 +199,10 @@ static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap)
206 { AUD_RDSI_SHIFT, 0x00000000 }, 199 { AUD_RDSI_SHIFT, 0x00000000 },
207 { AUD_RDSQ_SHIFT, 0x00000000 }, 200 { AUD_RDSQ_SHIFT, 0x00000000 },
208 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 201 { AUD_POLYPH80SCALEFAC, 0x00000003 },
209 { /* end of list */ }, 202 { /* end of list */ },
210 }; 203 };
211 static const struct rlist btsc_sap[] = { 204 static const struct rlist btsc_sap[] = {
205 { AUD_AFE_12DB_EN, 0x00000001 },
212 { AUD_DBX_IN_GAIN, 0x00007200 }, 206 { AUD_DBX_IN_GAIN, 0x00007200 },
213 { AUD_DBX_WBE_GAIN, 0x00006200 }, 207 { AUD_DBX_WBE_GAIN, 0x00006200 },
214 { AUD_DBX_SE_GAIN, 0x00006200 }, 208 { AUD_DBX_SE_GAIN, 0x00006200 },
@@ -259,371 +253,400 @@ static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap)
259 { AUD_RDSI_SHIFT, 0x00000000 }, 253 { AUD_RDSI_SHIFT, 0x00000000 },
260 { AUD_RDSQ_SHIFT, 0x00000000 }, 254 { AUD_RDSQ_SHIFT, 0x00000000 },
261 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 255 { AUD_POLYPH80SCALEFAC, 0x00000003 },
262 { /* end of list */ }, 256 { /* end of list */ },
263 }; 257 };
264 258
265 // dscaler: exactly taken from driver, 259 mode |= EN_FMRADIO_EN_RDS;
266 // dscaler: don't know why to set EN_FMRADIO_EN_RDS 260
267 if (sap) { 261 if (sap) {
268 dprintk("%s SAP (status: unknown)\n",__FUNCTION__); 262 dprintk("%s SAP (status: unknown)\n",__FUNCTION__);
269 set_audio_start(core, 0x0001, 263 set_audio_start(core, SEL_SAP);
270 EN_FMRADIO_EN_RDS | EN_BTSC_FORCE_SAP);
271 set_audio_registers(core, btsc_sap); 264 set_audio_registers(core, btsc_sap);
265 set_audio_finish(core, mode);
272 } else { 266 } else {
273 dprintk("%s (status: known-good)\n",__FUNCTION__); 267 dprintk("%s (status: known-good)\n",__FUNCTION__);
274 set_audio_start(core, 0x0001, 268 set_audio_start(core, SEL_BTSC);
275 EN_FMRADIO_EN_RDS | EN_BTSC_AUTO_STEREO);
276 set_audio_registers(core, btsc); 269 set_audio_registers(core, btsc);
270 set_audio_finish(core, mode);
277 } 271 }
278 set_audio_finish(core);
279} 272}
280 273
281 274
282static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo) 275static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo)
283{ 276{
284 /* This is probably weird.. 277 /* This is probably weird..
285 * Let's operate and find out. */ 278 * Let's operate and find out. */
286 279
287 static const struct rlist nicam_l_mono[] = { 280 static const struct rlist nicam_l_mono[] = {
288 { AUD_ERRLOGPERIOD_R, 0x00000064 }, 281 { AUD_ERRLOGPERIOD_R, 0x00000064 },
289 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF }, 282 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
290 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F }, 283 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
291 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F }, 284 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
292 285
293 { AUD_PDF_DDS_CNST_BYTE2, 0x48 }, 286 { AUD_PDF_DDS_CNST_BYTE2, 0x48 },
294 { AUD_PDF_DDS_CNST_BYTE1, 0x3D }, 287 { AUD_PDF_DDS_CNST_BYTE1, 0x3D },
295 { AUD_QAM_MODE, 0x00 }, 288 { AUD_QAM_MODE, 0x00 },
296 { AUD_PDF_DDS_CNST_BYTE0, 0xf5 }, 289 { AUD_PDF_DDS_CNST_BYTE0, 0xf5 },
297 { AUD_PHACC_FREQ_8MSB, 0x3a }, 290 { AUD_PHACC_FREQ_8MSB, 0x3a },
298 { AUD_PHACC_FREQ_8LSB, 0x4a }, 291 { AUD_PHACC_FREQ_8LSB, 0x4a },
299 292
300 { AUD_DEEMPHGAIN_R, 0x6680 }, 293 { AUD_DEEMPHGAIN_R, 0x6680 },
301 { AUD_DEEMPHNUMER1_R, 0x353DE }, 294 { AUD_DEEMPHNUMER1_R, 0x353DE },
302 { AUD_DEEMPHNUMER2_R, 0x1B1 }, 295 { AUD_DEEMPHNUMER2_R, 0x1B1 },
303 { AUD_DEEMPHDENOM1_R, 0x0F3D0 }, 296 { AUD_DEEMPHDENOM1_R, 0x0F3D0 },
304 { AUD_DEEMPHDENOM2_R, 0x0 }, 297 { AUD_DEEMPHDENOM2_R, 0x0 },
305 { AUD_FM_MODE_ENABLE, 0x7 }, 298 { AUD_FM_MODE_ENABLE, 0x7 },
306 { AUD_POLYPH80SCALEFAC, 0x3 }, 299 { AUD_POLYPH80SCALEFAC, 0x3 },
307 { AUD_AFE_12DB_EN, 0x1 }, 300 { AUD_AFE_12DB_EN, 0x1 },
308 { AAGC_GAIN, 0x0 }, 301 { AAGC_GAIN, 0x0 },
309 { AAGC_HYST, 0x18 }, 302 { AAGC_HYST, 0x18 },
310 { AAGC_DEF, 0x20 }, 303 { AAGC_DEF, 0x20 },
311 { AUD_DN0_FREQ, 0x0 }, 304 { AUD_DN0_FREQ, 0x0 },
312 { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 }, 305 { AUD_POLY0_DDS_CONSTANT, 0x0E4DB2 },
313 { AUD_DCOC_0_SRC, 0x21 }, 306 { AUD_DCOC_0_SRC, 0x21 },
314 { AUD_IIR1_0_SEL, 0x0 }, 307 { AUD_IIR1_0_SEL, 0x0 },
315 { AUD_IIR1_0_SHIFT, 0x7 }, 308 { AUD_IIR1_0_SHIFT, 0x7 },
316 { AUD_IIR1_1_SEL, 0x2 }, 309 { AUD_IIR1_1_SEL, 0x2 },
317 { AUD_IIR1_1_SHIFT, 0x0 }, 310 { AUD_IIR1_1_SHIFT, 0x0 },
318 { AUD_DCOC_1_SRC, 0x3 }, 311 { AUD_DCOC_1_SRC, 0x3 },
319 { AUD_DCOC1_SHIFT, 0x0 }, 312 { AUD_DCOC1_SHIFT, 0x0 },
320 { AUD_DCOC_PASS_IN, 0x0 }, 313 { AUD_DCOC_PASS_IN, 0x0 },
321 { AUD_IIR1_2_SEL, 0x23 }, 314 { AUD_IIR1_2_SEL, 0x23 },
322 { AUD_IIR1_2_SHIFT, 0x0 }, 315 { AUD_IIR1_2_SHIFT, 0x0 },
323 { AUD_IIR1_3_SEL, 0x4 }, 316 { AUD_IIR1_3_SEL, 0x4 },
324 { AUD_IIR1_3_SHIFT, 0x7 }, 317 { AUD_IIR1_3_SHIFT, 0x7 },
325 { AUD_IIR1_4_SEL, 0x5 }, 318 { AUD_IIR1_4_SEL, 0x5 },
326 { AUD_IIR1_4_SHIFT, 0x7 }, 319 { AUD_IIR1_4_SHIFT, 0x7 },
327 { AUD_IIR3_0_SEL, 0x7 }, 320 { AUD_IIR3_0_SEL, 0x7 },
328 { AUD_IIR3_0_SHIFT, 0x0 }, 321 { AUD_IIR3_0_SHIFT, 0x0 },
329 { AUD_DEEMPH0_SRC_SEL, 0x11 }, 322 { AUD_DEEMPH0_SRC_SEL, 0x11 },
330 { AUD_DEEMPH0_SHIFT, 0x0 }, 323 { AUD_DEEMPH0_SHIFT, 0x0 },
331 { AUD_DEEMPH0_G0, 0x7000 }, 324 { AUD_DEEMPH0_G0, 0x7000 },
332 { AUD_DEEMPH0_A0, 0x0 }, 325 { AUD_DEEMPH0_A0, 0x0 },
333 { AUD_DEEMPH0_B0, 0x0 }, 326 { AUD_DEEMPH0_B0, 0x0 },
334 { AUD_DEEMPH0_A1, 0x0 }, 327 { AUD_DEEMPH0_A1, 0x0 },
335 { AUD_DEEMPH0_B1, 0x0 }, 328 { AUD_DEEMPH0_B1, 0x0 },
336 { AUD_DEEMPH1_SRC_SEL, 0x11 }, 329 { AUD_DEEMPH1_SRC_SEL, 0x11 },
337 { AUD_DEEMPH1_SHIFT, 0x0 }, 330 { AUD_DEEMPH1_SHIFT, 0x0 },
338 { AUD_DEEMPH1_G0, 0x7000 }, 331 { AUD_DEEMPH1_G0, 0x7000 },
339 { AUD_DEEMPH1_A0, 0x0 }, 332 { AUD_DEEMPH1_A0, 0x0 },
340 { AUD_DEEMPH1_B0, 0x0 }, 333 { AUD_DEEMPH1_B0, 0x0 },
341 { AUD_DEEMPH1_A1, 0x0 }, 334 { AUD_DEEMPH1_A1, 0x0 },
342 { AUD_DEEMPH1_B1, 0x0 }, 335 { AUD_DEEMPH1_B1, 0x0 },
343 { AUD_OUT0_SEL, 0x3F }, 336 { AUD_OUT0_SEL, 0x3F },
344 { AUD_OUT1_SEL, 0x3F }, 337 { AUD_OUT1_SEL, 0x3F },
345 { AUD_DMD_RA_DDS, 0x0F5C285 }, 338 { AUD_DMD_RA_DDS, 0x0F5C285 },
346 { AUD_PLL_INT, 0x1E }, 339 { AUD_PLL_INT, 0x1E },
347 { AUD_PLL_DDS, 0x0 }, 340 { AUD_PLL_DDS, 0x0 },
348 { AUD_PLL_FRAC, 0x0E542 }, 341 { AUD_PLL_FRAC, 0x0E542 },
349 342
350 // setup QAM registers 343 // setup QAM registers
351 { AUD_RATE_ADJ1, 0x00000100 }, 344 { AUD_RATE_ADJ1, 0x00000100 },
352 { AUD_RATE_ADJ2, 0x00000200 }, 345 { AUD_RATE_ADJ2, 0x00000200 },
353 { AUD_RATE_ADJ3, 0x00000300 }, 346 { AUD_RATE_ADJ3, 0x00000300 },
354 { AUD_RATE_ADJ4, 0x00000400 }, 347 { AUD_RATE_ADJ4, 0x00000400 },
355 { AUD_RATE_ADJ5, 0x00000500 }, 348 { AUD_RATE_ADJ5, 0x00000500 },
356 { AUD_RATE_THRES_DMD, 0x000000C0 }, 349 { AUD_RATE_THRES_DMD, 0x000000C0 },
357 { /* end of list */ }, 350 { /* end of list */ },
358 }; 351 };
359
360 static const struct rlist nicam_l[] = {
361 // setup QAM registers
362 { AUD_RATE_ADJ1, 0x00000060 },
363 { AUD_RATE_ADJ2, 0x000000F9 },
364 { AUD_RATE_ADJ3, 0x000001CC },
365 { AUD_RATE_ADJ4, 0x000002B3 },
366 { AUD_RATE_ADJ5, 0x00000726 },
367 { AUD_DEEMPHDENOM1_R, 0x0000F3D0 },
368 { AUD_DEEMPHDENOM2_R, 0x00000000 },
369 { AUD_ERRLOGPERIOD_R, 0x00000064 },
370 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
371 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
372 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
373 { AUD_POLYPH80SCALEFAC, 0x00000003 },
374 { AUD_DMD_RA_DDS, 0x00C00000 },
375 { AUD_PLL_INT, 0x0000001E },
376 { AUD_PLL_DDS, 0x00000000 },
377 { AUD_PLL_FRAC, 0x0000E542 },
378 { AUD_START_TIMER, 0x00000000 },
379 { AUD_DEEMPHNUMER1_R, 0x000353DE },
380 { AUD_DEEMPHNUMER2_R, 0x000001B1 },
381 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
382 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
383 { AUD_QAM_MODE, 0x05 },
384 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
385 { AUD_PHACC_FREQ_8MSB, 0x34 },
386 { AUD_PHACC_FREQ_8LSB, 0x4C },
387 { AUD_DEEMPHGAIN_R, 0x00006680 },
388 { AUD_RATE_THRES_DMD, 0x000000C0 },
389 { /* end of list */ },
390 } ;
391 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
392
393 if (!stereo) {
394 /* AM mono sound */
395 set_audio_start(core, 0x0004,
396 0x100c /* FIXME again */);
397 set_audio_registers(core, nicam_l_mono);
398 } else {
399 set_audio_start(core, 0x0010,
400 0x1924 /* FIXME again */);
401 set_audio_registers(core, nicam_l);
402 }
403 set_audio_finish(core);
404 352
353 static const struct rlist nicam_l[] = {
354 // setup QAM registers
355 { AUD_RATE_ADJ1, 0x00000060 },
356 { AUD_RATE_ADJ2, 0x000000F9 },
357 { AUD_RATE_ADJ3, 0x000001CC },
358 { AUD_RATE_ADJ4, 0x000002B3 },
359 { AUD_RATE_ADJ5, 0x00000726 },
360 { AUD_DEEMPHDENOM1_R, 0x0000F3D0 },
361 { AUD_DEEMPHDENOM2_R, 0x00000000 },
362 { AUD_ERRLOGPERIOD_R, 0x00000064 },
363 { AUD_ERRINTRPTTHSHLD1_R, 0x00000FFF },
364 { AUD_ERRINTRPTTHSHLD2_R, 0x0000001F },
365 { AUD_ERRINTRPTTHSHLD3_R, 0x0000000F },
366 { AUD_POLYPH80SCALEFAC, 0x00000003 },
367 { AUD_DMD_RA_DDS, 0x00C00000 },
368 { AUD_PLL_INT, 0x0000001E },
369 { AUD_PLL_DDS, 0x00000000 },
370 { AUD_PLL_FRAC, 0x0000E542 },
371 { AUD_START_TIMER, 0x00000000 },
372 { AUD_DEEMPHNUMER1_R, 0x000353DE },
373 { AUD_DEEMPHNUMER2_R, 0x000001B1 },
374 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
375 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
376 { AUD_QAM_MODE, 0x05 },
377 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
378 { AUD_PHACC_FREQ_8MSB, 0x34 },
379 { AUD_PHACC_FREQ_8LSB, 0x4C },
380 { AUD_DEEMPHGAIN_R, 0x00006680 },
381 { AUD_RATE_THRES_DMD, 0x000000C0 },
382 { /* end of list */ },
383 } ;
384 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
385
386 if (!stereo) {
387 /* AM Mono */
388 set_audio_start(core, SEL_A2);
389 set_audio_registers(core, nicam_l_mono);
390 set_audio_finish(core, EN_A2_FORCE_MONO1);
391 } else {
392 /* Nicam Stereo */
393 set_audio_start(core, SEL_NICAM);
394 set_audio_registers(core, nicam_l);
395 set_audio_finish(core, 0x1924); /* FIXME */
396 }
405} 397}
406 398
407static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo) 399static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo)
408{ 400{
409 static const struct rlist pal_i_fm_mono[] = { 401 static const struct rlist pal_i_fm_mono[] = {
410 {AUD_ERRLOGPERIOD_R, 0x00000064}, 402 {AUD_ERRLOGPERIOD_R, 0x00000064},
411 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff}, 403 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
412 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f}, 404 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
413 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f}, 405 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
414 {AUD_PDF_DDS_CNST_BYTE2, 0x06}, 406 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
415 {AUD_PDF_DDS_CNST_BYTE1, 0x82}, 407 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
416 {AUD_PDF_DDS_CNST_BYTE0, 0x12}, 408 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
417 {AUD_QAM_MODE, 0x05}, 409 {AUD_QAM_MODE, 0x05},
418 {AUD_PHACC_FREQ_8MSB, 0x3a}, 410 {AUD_PHACC_FREQ_8MSB, 0x3a},
419 {AUD_PHACC_FREQ_8LSB, 0x93}, 411 {AUD_PHACC_FREQ_8LSB, 0x93},
420 {AUD_DMD_RA_DDS, 0x002a4f2f}, 412 {AUD_DMD_RA_DDS, 0x002a4f2f},
421 {AUD_PLL_INT, 0x0000001e}, 413 {AUD_PLL_INT, 0x0000001e},
422 {AUD_PLL_DDS, 0x00000004}, 414 {AUD_PLL_DDS, 0x00000004},
423 {AUD_PLL_FRAC, 0x0000e542}, 415 {AUD_PLL_FRAC, 0x0000e542},
424 {AUD_RATE_ADJ1, 0x00000100}, 416 {AUD_RATE_ADJ1, 0x00000100},
425 {AUD_RATE_ADJ2, 0x00000200}, 417 {AUD_RATE_ADJ2, 0x00000200},
426 {AUD_RATE_ADJ3, 0x00000300}, 418 {AUD_RATE_ADJ3, 0x00000300},
427 {AUD_RATE_ADJ4, 0x00000400}, 419 {AUD_RATE_ADJ4, 0x00000400},
428 {AUD_RATE_ADJ5, 0x00000500}, 420 {AUD_RATE_ADJ5, 0x00000500},
429 {AUD_THR_FR, 0x00000000}, 421 {AUD_THR_FR, 0x00000000},
430 {AUD_PILOT_BQD_1_K0, 0x0000755b}, 422 {AUD_PILOT_BQD_1_K0, 0x0000755b},
431 {AUD_PILOT_BQD_1_K1, 0x00551340}, 423 {AUD_PILOT_BQD_1_K1, 0x00551340},
432 {AUD_PILOT_BQD_1_K2, 0x006d30be}, 424 {AUD_PILOT_BQD_1_K2, 0x006d30be},
433 {AUD_PILOT_BQD_1_K3, 0xffd394af}, 425 {AUD_PILOT_BQD_1_K3, 0xffd394af},
434 {AUD_PILOT_BQD_1_K4, 0x00400000}, 426 {AUD_PILOT_BQD_1_K4, 0x00400000},
435 {AUD_PILOT_BQD_2_K0, 0x00040000}, 427 {AUD_PILOT_BQD_2_K0, 0x00040000},
436 {AUD_PILOT_BQD_2_K1, 0x002a4841}, 428 {AUD_PILOT_BQD_2_K1, 0x002a4841},
437 {AUD_PILOT_BQD_2_K2, 0x00400000}, 429 {AUD_PILOT_BQD_2_K2, 0x00400000},
438 {AUD_PILOT_BQD_2_K3, 0x00000000}, 430 {AUD_PILOT_BQD_2_K3, 0x00000000},
439 {AUD_PILOT_BQD_2_K4, 0x00000000}, 431 {AUD_PILOT_BQD_2_K4, 0x00000000},
440 {AUD_MODE_CHG_TIMER, 0x00000060}, 432 {AUD_MODE_CHG_TIMER, 0x00000060},
441 {AUD_AFE_12DB_EN, 0x00000001}, 433 {AUD_AFE_12DB_EN, 0x00000001},
442 {AAGC_HYST, 0x0000000a}, 434 {AAGC_HYST, 0x0000000a},
443 {AUD_CORDIC_SHIFT_0, 0x00000007}, 435 {AUD_CORDIC_SHIFT_0, 0x00000007},
444 {AUD_CORDIC_SHIFT_1, 0x00000007}, 436 {AUD_CORDIC_SHIFT_1, 0x00000007},
445 {AUD_C1_UP_THR, 0x00007000}, 437 {AUD_C1_UP_THR, 0x00007000},
446 {AUD_C1_LO_THR, 0x00005400}, 438 {AUD_C1_LO_THR, 0x00005400},
447 {AUD_C2_UP_THR, 0x00005400}, 439 {AUD_C2_UP_THR, 0x00005400},
448 {AUD_C2_LO_THR, 0x00003000}, 440 {AUD_C2_LO_THR, 0x00003000},
449 {AUD_DCOC_0_SRC, 0x0000001a}, 441 {AUD_DCOC_0_SRC, 0x0000001a},
450 {AUD_DCOC0_SHIFT, 0x00000000}, 442 {AUD_DCOC0_SHIFT, 0x00000000},
451 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a}, 443 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
452 {AUD_DCOC_0_SHIFT_IN1, 0x00000008}, 444 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
453 {AUD_DCOC_PASS_IN, 0x00000003}, 445 {AUD_DCOC_PASS_IN, 0x00000003},
454 {AUD_IIR3_0_SEL, 0x00000021}, 446 {AUD_IIR3_0_SEL, 0x00000021},
455 {AUD_DN2_AFC, 0x00000002}, 447 {AUD_DN2_AFC, 0x00000002},
456 {AUD_DCOC_1_SRC, 0x0000001b}, 448 {AUD_DCOC_1_SRC, 0x0000001b},
457 {AUD_DCOC1_SHIFT, 0x00000000}, 449 {AUD_DCOC1_SHIFT, 0x00000000},
458 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a}, 450 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
459 {AUD_DCOC_1_SHIFT_IN1, 0x00000008}, 451 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
460 {AUD_IIR3_1_SEL, 0x00000023}, 452 {AUD_IIR3_1_SEL, 0x00000023},
461 {AUD_DN0_FREQ, 0x000035a3}, 453 {AUD_DN0_FREQ, 0x000035a3},
462 {AUD_DN2_FREQ, 0x000029c7}, 454 {AUD_DN2_FREQ, 0x000029c7},
463 {AUD_CRDC0_SRC_SEL, 0x00000511}, 455 {AUD_CRDC0_SRC_SEL, 0x00000511},
464 {AUD_IIR1_0_SEL, 0x00000001}, 456 {AUD_IIR1_0_SEL, 0x00000001},
465 {AUD_IIR1_1_SEL, 0x00000000}, 457 {AUD_IIR1_1_SEL, 0x00000000},
466 {AUD_IIR3_2_SEL, 0x00000003}, 458 {AUD_IIR3_2_SEL, 0x00000003},
467 {AUD_IIR3_2_SHIFT, 0x00000000}, 459 {AUD_IIR3_2_SHIFT, 0x00000000},
468 {AUD_IIR3_0_SEL, 0x00000002}, 460 {AUD_IIR3_0_SEL, 0x00000002},
469 {AUD_IIR2_0_SEL, 0x00000021}, 461 {AUD_IIR2_0_SEL, 0x00000021},
470 {AUD_IIR2_0_SHIFT, 0x00000002}, 462 {AUD_IIR2_0_SHIFT, 0x00000002},
471 {AUD_DEEMPH0_SRC_SEL, 0x0000000b}, 463 {AUD_DEEMPH0_SRC_SEL, 0x0000000b},
472 {AUD_DEEMPH1_SRC_SEL, 0x0000000b}, 464 {AUD_DEEMPH1_SRC_SEL, 0x0000000b},
473 {AUD_POLYPH80SCALEFAC, 0x00000001}, 465 {AUD_POLYPH80SCALEFAC, 0x00000001},
474 {AUD_START_TIMER, 0x00000000}, 466 {AUD_START_TIMER, 0x00000000},
475 { /* end of list */ }, 467 { /* end of list */ },
476 }; 468 };
477 469
478 static const struct rlist pal_i_nicam[] = { 470 static const struct rlist pal_i_nicam[] = {
479 { AUD_RATE_ADJ1, 0x00000010 }, 471 { AUD_RATE_ADJ1, 0x00000010 },
480 { AUD_RATE_ADJ2, 0x00000040 }, 472 { AUD_RATE_ADJ2, 0x00000040 },
481 { AUD_RATE_ADJ3, 0x00000100 }, 473 { AUD_RATE_ADJ3, 0x00000100 },
482 { AUD_RATE_ADJ4, 0x00000400 }, 474 { AUD_RATE_ADJ4, 0x00000400 },
483 { AUD_RATE_ADJ5, 0x00001000 }, 475 { AUD_RATE_ADJ5, 0x00001000 },
484 // { AUD_DMD_RA_DDS, 0x00c0d5ce }, 476 // { AUD_DMD_RA_DDS, 0x00c0d5ce },
485 { AUD_DEEMPHGAIN_R, 0x000023c2 }, 477 { AUD_DEEMPHGAIN_R, 0x000023c2 },
486 { AUD_DEEMPHNUMER1_R, 0x0002a7bc }, 478 { AUD_DEEMPHNUMER1_R, 0x0002a7bc },
487 { AUD_DEEMPHNUMER2_R, 0x0003023e }, 479 { AUD_DEEMPHNUMER2_R, 0x0003023e },
488 { AUD_DEEMPHDENOM1_R, 0x0000f3d0 }, 480 { AUD_DEEMPHDENOM1_R, 0x0000f3d0 },
489 { AUD_DEEMPHDENOM2_R, 0x00000000 }, 481 { AUD_DEEMPHDENOM2_R, 0x00000000 },
490 { AUD_DEEMPHDENOM2_R, 0x00000000 }, 482 { AUD_DEEMPHDENOM2_R, 0x00000000 },
491 { AUD_ERRLOGPERIOD_R, 0x00000fff }, 483 { AUD_ERRLOGPERIOD_R, 0x00000fff },
492 { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff }, 484 { AUD_ERRINTRPTTHSHLD1_R, 0x000003ff },
493 { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff }, 485 { AUD_ERRINTRPTTHSHLD2_R, 0x000000ff },
494 { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f }, 486 { AUD_ERRINTRPTTHSHLD3_R, 0x0000003f },
495 { AUD_POLYPH80SCALEFAC, 0x00000003 }, 487 { AUD_POLYPH80SCALEFAC, 0x00000003 },
496 { AUD_PDF_DDS_CNST_BYTE2, 0x06 }, 488 { AUD_PDF_DDS_CNST_BYTE2, 0x06 },
497 { AUD_PDF_DDS_CNST_BYTE1, 0x82 }, 489 { AUD_PDF_DDS_CNST_BYTE1, 0x82 },
498 { AUD_PDF_DDS_CNST_BYTE0, 0x16 }, 490 { AUD_PDF_DDS_CNST_BYTE0, 0x16 },
499 { AUD_QAM_MODE, 0x05 }, 491 { AUD_QAM_MODE, 0x05 },
500 { AUD_PDF_DDS_CNST_BYTE0, 0x12 }, 492 { AUD_PDF_DDS_CNST_BYTE0, 0x12 },
501 { AUD_PHACC_FREQ_8MSB, 0x3a }, 493 { AUD_PHACC_FREQ_8MSB, 0x3a },
502 { AUD_PHACC_FREQ_8LSB, 0x93 }, 494 { AUD_PHACC_FREQ_8LSB, 0x93 },
503 { /* end of list */ }, 495 { /* end of list */ },
504 }; 496 };
505 497
506 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo); 498 dprintk("%s (status: devel), stereo : %d\n",__FUNCTION__,stereo);
507 499
508 if (!stereo) { 500 if (!stereo) {
509 // FM mono 501 /* FM Mono */
510 set_audio_start(core, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1); 502 set_audio_start(core, SEL_A2);
511 set_audio_registers(core, pal_i_fm_mono); 503 set_audio_registers(core, pal_i_fm_mono);
512 } else { 504 set_audio_finish(core, EN_DMTRX_SUMDIFF | EN_A2_FORCE_MONO1);
513 // Nicam Stereo 505 } else {
514 set_audio_start(core, 0x0010, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO); 506 /* Nicam Stereo */
507 set_audio_start(core, SEL_NICAM);
515 set_audio_registers(core, pal_i_nicam); 508 set_audio_registers(core, pal_i_nicam);
516 } 509 set_audio_finish(core, EN_DMTRX_LR | EN_DMTRX_BYPASS | EN_NICAM_AUTO_STEREO);
517 set_audio_finish(core); 510 }
518} 511}
519 512
520static void set_audio_standard_A2(struct cx88_core *core) 513static void set_audio_standard_A2(struct cx88_core *core, u32 mode)
521{ 514{
522 /* from dscaler cvs */
523 static const struct rlist a2_common[] = { 515 static const struct rlist a2_common[] = {
524 { AUD_PDF_DDS_CNST_BYTE2, 0x06 }, 516 {AUD_ERRLOGPERIOD_R, 0x00000064},
525 { AUD_PDF_DDS_CNST_BYTE1, 0x82 }, 517 {AUD_ERRINTRPTTHSHLD1_R, 0x00000fff},
526 { AUD_PDF_DDS_CNST_BYTE0, 0x12 }, 518 {AUD_ERRINTRPTTHSHLD2_R, 0x0000001f},
527 { AUD_QAM_MODE, 0x05 }, 519 {AUD_ERRINTRPTTHSHLD3_R, 0x0000000f},
528 { AUD_PHACC_FREQ_8MSB, 0x34 }, 520 {AUD_PDF_DDS_CNST_BYTE2, 0x06},
529 { AUD_PHACC_FREQ_8LSB, 0x4c }, 521 {AUD_PDF_DDS_CNST_BYTE1, 0x82},
530 522 {AUD_PDF_DDS_CNST_BYTE0, 0x12},
531 { AUD_RATE_ADJ1, 0x00001000 }, 523 {AUD_QAM_MODE, 0x05},
532 { AUD_RATE_ADJ2, 0x00002000 }, 524 {AUD_PHACC_FREQ_8MSB, 0x34},
533 { AUD_RATE_ADJ3, 0x00003000 }, 525 {AUD_PHACC_FREQ_8LSB, 0x4c},
534 { AUD_RATE_ADJ4, 0x00004000 }, 526 {AUD_RATE_ADJ1, 0x00000100},
535 { AUD_RATE_ADJ5, 0x00005000 }, 527 {AUD_RATE_ADJ2, 0x00000200},
536 { AUD_THR_FR, 0x00000000 }, 528 {AUD_RATE_ADJ3, 0x00000300},
537 { AAGC_HYST, 0x0000001a }, 529 {AUD_RATE_ADJ4, 0x00000400},
538 { AUD_PILOT_BQD_1_K0, 0x0000755b }, 530 {AUD_RATE_ADJ5, 0x00000500},
539 { AUD_PILOT_BQD_1_K1, 0x00551340 }, 531 {AUD_THR_FR, 0x00000000},
540 { AUD_PILOT_BQD_1_K2, 0x006d30be }, 532 {AAGC_HYST, 0x0000001a},
541 { AUD_PILOT_BQD_1_K3, 0xffd394af }, 533 {AUD_PILOT_BQD_1_K0, 0x0000755b},
542 { AUD_PILOT_BQD_1_K4, 0x00400000 }, 534 {AUD_PILOT_BQD_1_K1, 0x00551340},
543 { AUD_PILOT_BQD_2_K0, 0x00040000 }, 535 {AUD_PILOT_BQD_1_K2, 0x006d30be},
544 { AUD_PILOT_BQD_2_K1, 0x002a4841 }, 536 {AUD_PILOT_BQD_1_K3, 0xffd394af},
545 { AUD_PILOT_BQD_2_K2, 0x00400000 }, 537 {AUD_PILOT_BQD_1_K4, 0x00400000},
546 { AUD_PILOT_BQD_2_K3, 0x00000000 }, 538 {AUD_PILOT_BQD_2_K0, 0x00040000},
547 { AUD_PILOT_BQD_2_K4, 0x00000000 }, 539 {AUD_PILOT_BQD_2_K1, 0x002a4841},
548 { AUD_MODE_CHG_TIMER, 0x00000040 }, 540 {AUD_PILOT_BQD_2_K2, 0x00400000},
549 { AUD_START_TIMER, 0x00000200 }, 541 {AUD_PILOT_BQD_2_K3, 0x00000000},
550 { AUD_AFE_12DB_EN, 0x00000000 }, 542 {AUD_PILOT_BQD_2_K4, 0x00000000},
551 { AUD_CORDIC_SHIFT_0, 0x00000007 }, 543 {AUD_MODE_CHG_TIMER, 0x00000040},
552 { AUD_CORDIC_SHIFT_1, 0x00000007 }, 544 {AUD_AFE_12DB_EN, 0x00000001},
553 { AUD_DEEMPH0_G0, 0x00000380 }, 545 {AUD_CORDIC_SHIFT_0, 0x00000007},
554 { AUD_DEEMPH1_G0, 0x00000380 }, 546 {AUD_CORDIC_SHIFT_1, 0x00000007},
555 { AUD_DCOC_0_SRC, 0x0000001a }, 547 {AUD_DEEMPH0_G0, 0x00000380},
556 { AUD_DCOC0_SHIFT, 0x00000000 }, 548 {AUD_DEEMPH1_G0, 0x00000380},
557 { AUD_DCOC_0_SHIFT_IN0, 0x0000000a }, 549 {AUD_DCOC_0_SRC, 0x0000001a},
558 { AUD_DCOC_0_SHIFT_IN1, 0x00000008 }, 550 {AUD_DCOC0_SHIFT, 0x00000000},
559 { AUD_DCOC_PASS_IN, 0x00000003 }, 551 {AUD_DCOC_0_SHIFT_IN0, 0x0000000a},
560 { AUD_IIR3_0_SEL, 0x00000021 }, 552 {AUD_DCOC_0_SHIFT_IN1, 0x00000008},
561 { AUD_DN2_AFC, 0x00000002 }, 553 {AUD_DCOC_PASS_IN, 0x00000003},
562 { AUD_DCOC_1_SRC, 0x0000001b }, 554 {AUD_IIR3_0_SEL, 0x00000021},
563 { AUD_DCOC1_SHIFT, 0x00000000 }, 555 {AUD_DN2_AFC, 0x00000002},
564 { AUD_DCOC_1_SHIFT_IN0, 0x0000000a }, 556 {AUD_DCOC_1_SRC, 0x0000001b},
565 { AUD_DCOC_1_SHIFT_IN1, 0x00000008 }, 557 {AUD_DCOC1_SHIFT, 0x00000000},
566 { AUD_IIR3_1_SEL, 0x00000023 }, 558 {AUD_DCOC_1_SHIFT_IN0, 0x0000000a},
567 { AUD_RDSI_SEL, 0x00000017 }, 559 {AUD_DCOC_1_SHIFT_IN1, 0x00000008},
568 { AUD_RDSI_SHIFT, 0x00000000 }, 560 {AUD_IIR3_1_SEL, 0x00000023},
569 { AUD_RDSQ_SEL, 0x00000017 }, 561 {AUD_RDSI_SEL, 0x00000017},
570 { AUD_RDSQ_SHIFT, 0x00000000 }, 562 {AUD_RDSI_SHIFT, 0x00000000},
571 { AUD_POLYPH80SCALEFAC, 0x00000001 }, 563 {AUD_RDSQ_SEL, 0x00000017},
564 {AUD_RDSQ_SHIFT, 0x00000000},
565 {AUD_PLL_INT, 0x0000001e},
566 {AUD_PLL_DDS, 0x00000000},
567 {AUD_PLL_FRAC, 0x0000e542},
568 {AUD_POLYPH80SCALEFAC, 0x00000001},
569 {AUD_START_TIMER, 0x00000000},
570 { /* end of list */ },
571 };
572 572
573 static const struct rlist a2_bg[] = {
574 {AUD_DMD_RA_DDS, 0x002a4f2f},
575 {AUD_C1_UP_THR, 0x00007000},
576 {AUD_C1_LO_THR, 0x00005400},
577 {AUD_C2_UP_THR, 0x00005400},
578 {AUD_C2_LO_THR, 0x00003000},
573 { /* end of list */ }, 579 { /* end of list */ },
574 }; 580 };
575 581
576 static const struct rlist a2_table1[] = { 582 static const struct rlist a2_dk[] = {
577 // PAL-BG 583 {AUD_DMD_RA_DDS, 0x002a4f2f},
578 { AUD_DMD_RA_DDS, 0x002a73bd }, 584 {AUD_C1_UP_THR, 0x00007000},
579 { AUD_C1_UP_THR, 0x00007000 }, 585 {AUD_C1_LO_THR, 0x00005400},
580 { AUD_C1_LO_THR, 0x00005400 }, 586 {AUD_C2_UP_THR, 0x00005400},
581 { AUD_C2_UP_THR, 0x00005400 }, 587 {AUD_C2_LO_THR, 0x00003000},
582 { AUD_C2_LO_THR, 0x00003000 }, 588 {AUD_DN0_FREQ, 0x00003a1c},
589 {AUD_DN2_FREQ, 0x0000d2e0},
583 { /* end of list */ }, 590 { /* end of list */ },
584 }; 591 };
585 static const struct rlist a2_table2[] = { 592/* unknown, probably NTSC-M */
586 // PAL-DK 593 static const struct rlist a2_m[] = {
587 { AUD_DMD_RA_DDS, 0x002a73bd }, 594 {AUD_DMD_RA_DDS, 0x002a0425},
588 { AUD_C1_UP_THR, 0x00007000 }, 595 {AUD_C1_UP_THR, 0x00003c00},
589 { AUD_C1_LO_THR, 0x00005400 }, 596 {AUD_C1_LO_THR, 0x00003000},
590 { AUD_C2_UP_THR, 0x00005400 }, 597 {AUD_C2_UP_THR, 0x00006000},
591 { AUD_C2_LO_THR, 0x00003000 }, 598 {AUD_C2_LO_THR, 0x00003c00},
592 { AUD_DN0_FREQ, 0x00003a1c }, 599 {AUD_DEEMPH0_A0, 0x00007a80},
593 { AUD_DN2_FREQ, 0x0000d2e0 }, 600 {AUD_DEEMPH1_A0, 0x00007a80},
601 {AUD_DEEMPH0_G0, 0x00001200},
602 {AUD_DEEMPH1_G0, 0x00001200},
603 {AUD_DN0_FREQ, 0x0000283b},
604 {AUD_DN1_FREQ, 0x00003418},
605 {AUD_DN2_FREQ, 0x000029c7},
606 {AUD_POLY0_DDS_CONSTANT, 0x000a7540},
594 { /* end of list */ }, 607 { /* end of list */ },
595 }; 608 };
596 static const struct rlist a2_table3[] = { 609
597 // unknown, probably NTSC-M 610 static const struct rlist a2_deemph50[] = {
598 { AUD_DMD_RA_DDS, 0x002a2873 }, 611 {AUD_DEEMPH0_G0, 0x00000380},
599 { AUD_C1_UP_THR, 0x00003c00 }, 612 {AUD_DEEMPH1_G0, 0x00000380},
600 { AUD_C1_LO_THR, 0x00003000 }, 613 {AUD_DEEMPHGAIN_R, 0x000011e1},
601 { AUD_C2_UP_THR, 0x00006000 }, 614 {AUD_DEEMPHNUMER1_R, 0x0002a7bc},
602 { AUD_C2_LO_THR, 0x00003c00 }, 615 {AUD_DEEMPHNUMER2_R, 0x0003023c},
603 { AUD_DN0_FREQ, 0x00002836 }, 616 { /* end of list */ },
604 { AUD_DN1_FREQ, 0x00003418 }, 617 };
605 { AUD_DN2_FREQ, 0x000029c7 }, 618
606 { AUD_POLY0_DDS_CONSTANT, 0x000a7540 }, 619 static const struct rlist a2_deemph75[] = {
620 {AUD_DEEMPH0_G0, 0x00000480},
621 {AUD_DEEMPH1_G0, 0x00000480},
622 {AUD_DEEMPHGAIN_R, 0x00009000},
623 {AUD_DEEMPHNUMER1_R, 0x000353de},
624 {AUD_DEEMPHNUMER2_R, 0x000001b1},
607 { /* end of list */ }, 625 { /* end of list */ },
608 }; 626 };
609 627
610 set_audio_start(core, 0x0004, EN_DMTRX_SUMDIFF | EN_A2_AUTO_STEREO); 628 set_audio_start(core, SEL_A2);
611 set_audio_registers(core, a2_common); 629 set_audio_registers(core, a2_common);
612 switch (core->tvaudio) { 630 switch (core->tvaudio) {
613 case WW_A2_BG: 631 case WW_A2_BG:
614 dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__); 632 dprintk("%s PAL-BG A2 (status: known-good)\n",__FUNCTION__);
615 set_audio_registers(core, a2_table1); 633 set_audio_registers(core, a2_bg);
634 set_audio_registers(core, a2_deemph50);
616 break; 635 break;
617 case WW_A2_DK: 636 case WW_A2_DK:
618 dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__); 637 dprintk("%s PAL-DK A2 (status: known-good)\n",__FUNCTION__);
619 set_audio_registers(core, a2_table2); 638 set_audio_registers(core, a2_dk);
639 set_audio_registers(core, a2_deemph50);
620 break; 640 break;
621 case WW_A2_M: 641 case WW_A2_M:
622 dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__); 642 dprintk("%s NTSC-M A2 (status: unknown)\n",__FUNCTION__);
623 set_audio_registers(core, a2_table3); 643 set_audio_registers(core, a2_m);
644 set_audio_registers(core, a2_deemph75);
624 break; 645 break;
625 }; 646 };
626 set_audio_finish(core); 647
648 mode |= EN_FMRADIO_EN_RDS | EN_DMTRX_SUMDIFF;
649 set_audio_finish(core, mode);
627} 650}
628 651
629static void set_audio_standard_EIAJ(struct cx88_core *core) 652static void set_audio_standard_EIAJ(struct cx88_core *core)
@@ -635,9 +658,9 @@ static void set_audio_standard_EIAJ(struct cx88_core *core)
635 }; 658 };
636 dprintk("%s (status: unknown)\n",__FUNCTION__); 659 dprintk("%s (status: unknown)\n",__FUNCTION__);
637 660
638 set_audio_start(core, 0x0002, EN_EIAJ_AUTO_STEREO); 661 set_audio_start(core, SEL_EIAJ);
639 set_audio_registers(core, eiaj); 662 set_audio_registers(core, eiaj);
640 set_audio_finish(core); 663 set_audio_finish(core, EN_EIAJ_AUTO_STEREO);
641} 664}
642 665
643static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph) 666static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph)
@@ -683,7 +706,7 @@ static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type
683 }; 706 };
684 707
685 dprintk("%s (status: unknown)\n",__FUNCTION__); 708 dprintk("%s (status: unknown)\n",__FUNCTION__);
686 set_audio_start(core, 0x0020, EN_FMRADIO_AUTO_STEREO); 709 set_audio_start(core, SEL_FMRADIO);
687 710
688 switch (deemph) 711 switch (deemph)
689 { 712 {
@@ -700,7 +723,7 @@ static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type
700 break; 723 break;
701 } 724 }
702 725
703 set_audio_finish(core); 726 set_audio_finish(core, EN_FMRADIO_AUTO_STEREO);
704} 727}
705 728
706/* ----------------------------------------------------------- */ 729/* ----------------------------------------------------------- */
@@ -709,7 +732,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
709{ 732{
710 switch (core->tvaudio) { 733 switch (core->tvaudio) {
711 case WW_BTSC: 734 case WW_BTSC:
712 set_audio_standard_BTSC(core,0); 735 set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
713 break; 736 break;
714 case WW_NICAM_BGDKL: 737 case WW_NICAM_BGDKL:
715 set_audio_standard_NICAM_L(core,0); 738 set_audio_standard_NICAM_L(core,0);
@@ -720,7 +743,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
720 case WW_A2_BG: 743 case WW_A2_BG:
721 case WW_A2_DK: 744 case WW_A2_DK:
722 case WW_A2_M: 745 case WW_A2_M:
723 set_audio_standard_A2(core); 746 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
724 break; 747 break;
725 case WW_EIAJ: 748 case WW_EIAJ:
726 set_audio_standard_EIAJ(core); 749 set_audio_standard_EIAJ(core);
@@ -734,7 +757,7 @@ void cx88_set_tvaudio(struct cx88_core *core)
734 case WW_NONE: 757 case WW_NONE:
735 default: 758 default:
736 printk("%s/0: unknown tv audio mode [%d]\n", 759 printk("%s/0: unknown tv audio mode [%d]\n",
737 core->name, core->tvaudio); 760 core->name, core->tvaudio);
738 break; 761 break;
739 } 762 }
740 return; 763 return;
@@ -769,6 +792,13 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
769 aud_ctl_names[cx_read(AUD_CTL) & 63]); 792 aud_ctl_names[cx_read(AUD_CTL) & 63]);
770 core->astat = reg; 793 core->astat = reg;
771 794
795/* TODO
796 Reading from AUD_STATUS is not enough
797 for auto-detecting sap/dual-fm/nicam.
798 Add some code here later.
799*/
800
801# if 0
772 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP | 802 t->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_SAP |
773 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; 803 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
774 t->rxsubchans = V4L2_TUNER_SUB_MONO; 804 t->rxsubchans = V4L2_TUNER_SUB_MONO;
@@ -779,7 +809,7 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
779 t->capability = V4L2_TUNER_CAP_STEREO | 809 t->capability = V4L2_TUNER_CAP_STEREO |
780 V4L2_TUNER_CAP_SAP; 810 V4L2_TUNER_CAP_SAP;
781 t->rxsubchans = V4L2_TUNER_SUB_STEREO; 811 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
782 if (1 == pilot) { 812 if (1 == pilot) {
783 /* SAP */ 813 /* SAP */
784 t->rxsubchans |= V4L2_TUNER_SUB_SAP; 814 t->rxsubchans |= V4L2_TUNER_SUB_SAP;
785 } 815 }
@@ -787,13 +817,13 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
787 case WW_A2_BG: 817 case WW_A2_BG:
788 case WW_A2_DK: 818 case WW_A2_DK:
789 case WW_A2_M: 819 case WW_A2_M:
790 if (1 == pilot) { 820 if (1 == pilot) {
791 /* stereo */ 821 /* stereo */
792 t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; 822 t->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
793 if (0 == mode) 823 if (0 == mode)
794 t->audmode = V4L2_TUNER_MODE_STEREO; 824 t->audmode = V4L2_TUNER_MODE_STEREO;
795 } 825 }
796 if (2 == pilot) { 826 if (2 == pilot) {
797 /* dual language -- FIXME */ 827 /* dual language -- FIXME */
798 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; 828 t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
799 t->audmode = V4L2_TUNER_MODE_LANG1; 829 t->audmode = V4L2_TUNER_MODE_LANG1;
@@ -805,16 +835,17 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t)
805 t->rxsubchans |= V4L2_TUNER_SUB_STEREO; 835 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
806 } 836 }
807 break; 837 break;
808 case WW_SYSTEM_L_AM: 838 case WW_SYSTEM_L_AM:
809 if (0x0 == mode && !(cx_read(AUD_INIT) & 0x04)) { 839 if (0x0 == mode && !(cx_read(AUD_INIT) & 0x04)) {
810 t->audmode = V4L2_TUNER_MODE_STEREO; 840 t->audmode = V4L2_TUNER_MODE_STEREO;
811 t->rxsubchans |= V4L2_TUNER_SUB_STEREO; 841 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
812 } 842 }
813 break ; 843 break ;
814 default: 844 default:
815 /* nothing */ 845 /* nothing */
816 break; 846 break;
817 } 847 }
848# endif
818 return; 849 return;
819} 850}
820 851
@@ -835,16 +866,16 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
835 case WW_BTSC: 866 case WW_BTSC:
836 switch (mode) { 867 switch (mode) {
837 case V4L2_TUNER_MODE_MONO: 868 case V4L2_TUNER_MODE_MONO:
838 ctl = EN_BTSC_FORCE_MONO; 869 set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_MONO);
839 mask = 0x3f;
840 break; 870 break;
841 case V4L2_TUNER_MODE_SAP: 871 case V4L2_TUNER_MODE_LANG1:
842 ctl = EN_BTSC_FORCE_SAP; 872 set_audio_standard_BTSC(core, 0, EN_BTSC_AUTO_STEREO);
843 mask = 0x3f; 873 break;
874 case V4L2_TUNER_MODE_LANG2:
875 set_audio_standard_BTSC(core, 1, EN_BTSC_FORCE_SAP);
844 break; 876 break;
845 case V4L2_TUNER_MODE_STEREO: 877 case V4L2_TUNER_MODE_STEREO:
846 ctl = EN_BTSC_AUTO_STEREO; 878 set_audio_standard_BTSC(core, 0, EN_BTSC_FORCE_STEREO);
847 mask = 0x3f;
848 break; 879 break;
849 } 880 }
850 break; 881 break;
@@ -854,16 +885,13 @@ void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual)
854 switch (mode) { 885 switch (mode) {
855 case V4L2_TUNER_MODE_MONO: 886 case V4L2_TUNER_MODE_MONO:
856 case V4L2_TUNER_MODE_LANG1: 887 case V4L2_TUNER_MODE_LANG1:
857 ctl = EN_A2_FORCE_MONO1; 888 set_audio_standard_A2(core, EN_A2_FORCE_MONO1);
858 mask = 0x3f;
859 break; 889 break;
860 case V4L2_TUNER_MODE_LANG2: 890 case V4L2_TUNER_MODE_LANG2:
861 ctl = EN_A2_AUTO_MONO2; 891 set_audio_standard_A2(core, EN_A2_FORCE_MONO2);
862 mask = 0x3f;
863 break; 892 break;
864 case V4L2_TUNER_MODE_STEREO: 893 case V4L2_TUNER_MODE_STEREO:
865 ctl = EN_A2_AUTO_STEREO | EN_DMTRX_SUMR; 894 set_audio_standard_A2(core, EN_A2_FORCE_STEREO);
866 mask = 0x8bf;
867 break; 895 break;
868 } 896 }
869 break; 897 break;
diff --git a/drivers/media/video/cx88/cx88-vbi.c b/drivers/media/video/cx88/cx88-vbi.c
index 320d57888bb..9bc6c899558 100644
--- a/drivers/media/video/cx88/cx88-vbi.c
+++ b/drivers/media/video/cx88/cx88-vbi.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-vbi.c,v 1.17 2005/06/12 04:19:19 mchehab Exp $
3 */ 2 */
4#include <linux/kernel.h> 3#include <linux/kernel.h>
5#include <linux/module.h> 4#include <linux/module.h>
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 5f58c103198..61d4b29ec30 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88-video.c,v 1.82 2005/07/22 05:13:34 mkrufky Exp $
3 * 2 *
4 * device driver for Conexant 2388x based TV cards 3 * device driver for Conexant 2388x based TV cards
5 * video4linux video interface 4 * video4linux video interface
@@ -66,7 +65,7 @@ module_param(vid_limit,int,0644);
66MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); 65MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes");
67 66
68#define dprintk(level,fmt, arg...) if (video_debug >= level) \ 67#define dprintk(level,fmt, arg...) if (video_debug >= level) \
69 printk(KERN_DEBUG "%s/0: " fmt, dev->core->name , ## arg) 68 printk(KERN_DEBUG "%s/0: " fmt, core->name , ## arg)
70 69
71/* ------------------------------------------------------------------ */ 70/* ------------------------------------------------------------------ */
72 71
@@ -326,22 +325,23 @@ static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
326 325
327static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit) 326static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit)
328{ 327{
328 struct cx88_core *core = dev->core;
329 if (fh->resources & bit) 329 if (fh->resources & bit)
330 /* have it already allocated */ 330 /* have it already allocated */
331 return 1; 331 return 1;
332 332
333 /* is it free? */ 333 /* is it free? */
334 down(&dev->lock); 334 down(&core->lock);
335 if (dev->resources & bit) { 335 if (dev->resources & bit) {
336 /* no, someone else uses it */ 336 /* no, someone else uses it */
337 up(&dev->lock); 337 up(&core->lock);
338 return 0; 338 return 0;
339 } 339 }
340 /* it's free, grab it */ 340 /* it's free, grab it */
341 fh->resources |= bit; 341 fh->resources |= bit;
342 dev->resources |= bit; 342 dev->resources |= bit;
343 dprintk(1,"res: get %d\n",bit); 343 dprintk(1,"res: get %d\n",bit);
344 up(&dev->lock); 344 up(&core->lock);
345 return 1; 345 return 1;
346} 346}
347 347
@@ -360,27 +360,29 @@ int res_locked(struct cx8800_dev *dev, unsigned int bit)
360static 360static
361void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits) 361void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits)
362{ 362{
363 struct cx88_core *core = dev->core;
363 if ((fh->resources & bits) != bits) 364 if ((fh->resources & bits) != bits)
364 BUG(); 365 BUG();
365 366
366 down(&dev->lock); 367 down(&core->lock);
367 fh->resources &= ~bits; 368 fh->resources &= ~bits;
368 dev->resources &= ~bits; 369 dev->resources &= ~bits;
369 dprintk(1,"res: put %d\n",bits); 370 dprintk(1,"res: put %d\n",bits);
370 up(&dev->lock); 371 up(&core->lock);
371} 372}
372 373
373/* ------------------------------------------------------------------ */ 374/* ------------------------------------------------------------------ */
374 375
375static int video_mux(struct cx8800_dev *dev, unsigned int input) 376/* static int video_mux(struct cx8800_dev *dev, unsigned int input) */
377static int video_mux(struct cx88_core *core, unsigned int input)
376{ 378{
377 struct cx88_core *core = dev->core; 379 /* struct cx88_core *core = dev->core; */
378 380
379 dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n", 381 dprintk(1,"video_mux: %d [vmux=%d,gpio=0x%x,0x%x,0x%x,0x%x]\n",
380 input, INPUT(input)->vmux, 382 input, INPUT(input)->vmux,
381 INPUT(input)->gpio0,INPUT(input)->gpio1, 383 INPUT(input)->gpio0,INPUT(input)->gpio1,
382 INPUT(input)->gpio2,INPUT(input)->gpio3); 384 INPUT(input)->gpio2,INPUT(input)->gpio3);
383 dev->core->input = input; 385 core->input = input;
384 cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input)->vmux << 14); 386 cx_andor(MO_INPUT_FORMAT, 0x03 << 14, INPUT(input)->vmux << 14);
385 cx_write(MO_GP3_IO, INPUT(input)->gpio3); 387 cx_write(MO_GP3_IO, INPUT(input)->gpio3);
386 cx_write(MO_GP0_IO, INPUT(input)->gpio0); 388 cx_write(MO_GP0_IO, INPUT(input)->gpio0);
@@ -413,9 +415,9 @@ static int start_video_dma(struct cx8800_dev *dev,
413 struct cx88_core *core = dev->core; 415 struct cx88_core *core = dev->core;
414 416
415 /* setup fifo + format */ 417 /* setup fifo + format */
416 cx88_sram_channel_setup(dev->core, &cx88_sram_channels[SRAM_CH21], 418 cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH21],
417 buf->bpl, buf->risc.dma); 419 buf->bpl, buf->risc.dma);
418 cx88_set_scale(dev->core, buf->vb.width, buf->vb.height, buf->vb.field); 420 cx88_set_scale(core, buf->vb.width, buf->vb.height, buf->vb.field);
419 cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma); 421 cx_write(MO_COLOR_CTRL, buf->fmt->cxformat | ColorFormatGamma);
420 422
421 /* reset counter */ 423 /* reset counter */
@@ -424,6 +426,14 @@ static int start_video_dma(struct cx8800_dev *dev,
424 426
425 /* enable irqs */ 427 /* enable irqs */
426 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01); 428 cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x01);
429
430 /* Enables corresponding bits at PCI_INT_STAT:
431 bits 0 to 4: video, audio, transport stream, VIP, Host
432 bit 7: timer
433 bits 8 and 9: DMA complete for: SRC, DST
434 bits 10 and 11: BERR signal asserted for RISC: RD, WR
435 bits 12 to 15: BERR signal asserted for: BRDG, SRC, DST, IPB
436 */
427 cx_set(MO_VID_INTMSK, 0x0f0011); 437 cx_set(MO_VID_INTMSK, 0x0f0011);
428 438
429 /* enable capture */ 439 /* enable capture */
@@ -431,7 +441,7 @@ static int start_video_dma(struct cx8800_dev *dev,
431 441
432 /* start dma */ 442 /* start dma */
433 cx_set(MO_DEV_CNTRL2, (1<<5)); 443 cx_set(MO_DEV_CNTRL2, (1<<5));
434 cx_set(MO_VID_DMACNTRL, 0x11); 444 cx_set(MO_VID_DMACNTRL, 0x11); /* Planar Y and packed FIFO and RISC enable */
435 445
436 return 0; 446 return 0;
437} 447}
@@ -455,6 +465,7 @@ static int stop_video_dma(struct cx8800_dev *dev)
455static int restart_video_queue(struct cx8800_dev *dev, 465static int restart_video_queue(struct cx8800_dev *dev,
456 struct cx88_dmaqueue *q) 466 struct cx88_dmaqueue *q)
457{ 467{
468 struct cx88_core *core = dev->core;
458 struct cx88_buffer *buf, *prev; 469 struct cx88_buffer *buf, *prev;
459 struct list_head *item; 470 struct list_head *item;
460 471
@@ -524,12 +535,13 @@ buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
524{ 535{
525 struct cx8800_fh *fh = q->priv_data; 536 struct cx8800_fh *fh = q->priv_data;
526 struct cx8800_dev *dev = fh->dev; 537 struct cx8800_dev *dev = fh->dev;
538 struct cx88_core *core = dev->core;
527 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb); 539 struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
528 int rc, init_buffer = 0; 540 int rc, init_buffer = 0;
529 541
530 BUG_ON(NULL == fh->fmt); 542 BUG_ON(NULL == fh->fmt);
531 if (fh->width < 48 || fh->width > norm_maxw(dev->core->tvnorm) || 543 if (fh->width < 48 || fh->width > norm_maxw(core->tvnorm) ||
532 fh->height < 32 || fh->height > norm_maxh(dev->core->tvnorm)) 544 fh->height < 32 || fh->height > norm_maxh(core->tvnorm))
533 return -EINVAL; 545 return -EINVAL;
534 buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; 546 buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
535 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 547 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
@@ -609,6 +621,7 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
609 struct cx88_buffer *prev; 621 struct cx88_buffer *prev;
610 struct cx8800_fh *fh = vq->priv_data; 622 struct cx8800_fh *fh = vq->priv_data;
611 struct cx8800_dev *dev = fh->dev; 623 struct cx8800_dev *dev = fh->dev;
624 struct cx88_core *core = dev->core;
612 struct cx88_dmaqueue *q = &dev->vidq; 625 struct cx88_dmaqueue *q = &dev->vidq;
613 626
614 /* add jump to stopper */ 627 /* add jump to stopper */
@@ -701,6 +714,7 @@ static int video_open(struct inode *inode, struct file *file)
701{ 714{
702 int minor = iminor(inode); 715 int minor = iminor(inode);
703 struct cx8800_dev *h,*dev = NULL; 716 struct cx8800_dev *h,*dev = NULL;
717 struct cx88_core *core;
704 struct cx8800_fh *fh; 718 struct cx8800_fh *fh;
705 struct list_head *list; 719 struct list_head *list;
706 enum v4l2_buf_type type = 0; 720 enum v4l2_buf_type type = 0;
@@ -725,6 +739,8 @@ static int video_open(struct inode *inode, struct file *file)
725 if (NULL == dev) 739 if (NULL == dev)
726 return -ENODEV; 740 return -ENODEV;
727 741
742 core = dev->core;
743
728 dprintk(1,"open minor=%d radio=%d type=%s\n", 744 dprintk(1,"open minor=%d radio=%d type=%s\n",
729 minor,radio,v4l2_type_names[type]); 745 minor,radio,v4l2_type_names[type]);
730 746
@@ -755,17 +771,16 @@ static int video_open(struct inode *inode, struct file *file)
755 fh); 771 fh);
756 772
757 if (fh->radio) { 773 if (fh->radio) {
758 struct cx88_core *core = dev->core;
759 int board = core->board; 774 int board = core->board;
760 dprintk(1,"video_open: setting radio device\n"); 775 dprintk(1,"video_open: setting radio device\n");
761 cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3); 776 cx_write(MO_GP3_IO, cx88_boards[board].radio.gpio3);
762 cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0); 777 cx_write(MO_GP0_IO, cx88_boards[board].radio.gpio0);
763 cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1); 778 cx_write(MO_GP1_IO, cx88_boards[board].radio.gpio1);
764 cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2); 779 cx_write(MO_GP2_IO, cx88_boards[board].radio.gpio2);
765 dev->core->tvaudio = WW_FM; 780 core->tvaudio = WW_FM;
766 cx88_set_tvaudio(core); 781 cx88_set_tvaudio(core);
767 cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1); 782 cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
768 cx88_call_i2c_clients(dev->core,AUDC_SET_RADIO,NULL); 783 cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
769 } 784 }
770 785
771 return 0; 786 return 0;
@@ -857,6 +872,9 @@ static int video_release(struct inode *inode, struct file *file)
857 videobuf_mmap_free(&fh->vbiq); 872 videobuf_mmap_free(&fh->vbiq);
858 file->private_data = NULL; 873 file->private_data = NULL;
859 kfree(fh); 874 kfree(fh);
875
876 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
877
860 return 0; 878 return 0;
861} 879}
862 880
@@ -870,9 +888,10 @@ video_mmap(struct file *file, struct vm_area_struct * vma)
870 888
871/* ------------------------------------------------------------------ */ 889/* ------------------------------------------------------------------ */
872 890
873static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) 891/* static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) */
892static int get_control(struct cx88_core *core, struct v4l2_control *ctl)
874{ 893{
875 struct cx88_core *core = dev->core; 894 /* struct cx88_core *core = dev->core; */
876 struct cx88_ctrl *c = NULL; 895 struct cx88_ctrl *c = NULL;
877 u32 value; 896 u32 value;
878 int i; 897 int i;
@@ -898,9 +917,10 @@ static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
898 return 0; 917 return 0;
899} 918}
900 919
901static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) 920/* static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) */
921static int set_control(struct cx88_core *core, struct v4l2_control *ctl)
902{ 922{
903 struct cx88_core *core = dev->core; 923 /* struct cx88_core *core = dev->core; */
904 struct cx88_ctrl *c = NULL; 924 struct cx88_ctrl *c = NULL;
905 u32 v_sat_value; 925 u32 v_sat_value;
906 u32 value; 926 u32 value;
@@ -913,9 +933,9 @@ static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
913 return -EINVAL; 933 return -EINVAL;
914 934
915 if (ctl->value < c->v.minimum) 935 if (ctl->value < c->v.minimum)
916 return -ERANGE; 936 ctl->value = c->v.minimum;
917 if (ctl->value > c->v.maximum) 937 if (ctl->value > c->v.maximum)
918 return -ERANGE; 938 ctl->value = c->v.maximum;
919 switch (ctl->id) { 939 switch (ctl->id) {
920 case V4L2_CID_AUDIO_BALANCE: 940 case V4L2_CID_AUDIO_BALANCE:
921 value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value; 941 value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value;
@@ -946,7 +966,8 @@ static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl)
946 return 0; 966 return 0;
947} 967}
948 968
949static void init_controls(struct cx8800_dev *dev) 969/* static void init_controls(struct cx8800_dev *dev) */
970static void init_controls(struct cx88_core *core)
950{ 971{
951 static struct v4l2_control mute = { 972 static struct v4l2_control mute = {
952 .id = V4L2_CID_AUDIO_MUTE, 973 .id = V4L2_CID_AUDIO_MUTE,
@@ -969,11 +990,11 @@ static void init_controls(struct cx8800_dev *dev)
969 .value = 0x80, 990 .value = 0x80,
970 }; 991 };
971 992
972 set_control(dev,&mute); 993 set_control(core,&mute);
973 set_control(dev,&volume); 994 set_control(core,&volume);
974 set_control(dev,&hue); 995 set_control(core,&hue);
975 set_control(dev,&contrast); 996 set_control(core,&contrast);
976 set_control(dev,&brightness); 997 set_control(core,&brightness);
977} 998}
978 999
979/* ------------------------------------------------------------------ */ 1000/* ------------------------------------------------------------------ */
@@ -1004,6 +1025,8 @@ static int cx8800_g_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
1004static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh, 1025static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
1005 struct v4l2_format *f) 1026 struct v4l2_format *f)
1006{ 1027{
1028 struct cx88_core *core = dev->core;
1029
1007 switch (f->type) { 1030 switch (f->type) {
1008 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 1031 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1009 { 1032 {
@@ -1016,8 +1039,8 @@ static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh,
1016 return -EINVAL; 1039 return -EINVAL;
1017 1040
1018 field = f->fmt.pix.field; 1041 field = f->fmt.pix.field;
1019 maxw = norm_maxw(dev->core->tvnorm); 1042 maxw = norm_maxw(core->tvnorm);
1020 maxh = norm_maxh(dev->core->tvnorm); 1043 maxh = norm_maxh(core->tvnorm);
1021 1044
1022 if (V4L2_FIELD_ANY == field) { 1045 if (V4L2_FIELD_ANY == field) {
1023 field = (f->fmt.pix.height > maxh/2) 1046 field = (f->fmt.pix.height > maxh/2)
@@ -1101,12 +1124,14 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1101 if (video_debug > 1) 1124 if (video_debug > 1)
1102 cx88_print_ioctl(core->name,cmd); 1125 cx88_print_ioctl(core->name,cmd);
1103 switch (cmd) { 1126 switch (cmd) {
1127
1128 /* --- capabilities ------------------------------------------ */
1104 case VIDIOC_QUERYCAP: 1129 case VIDIOC_QUERYCAP:
1105 { 1130 {
1106 struct v4l2_capability *cap = arg; 1131 struct v4l2_capability *cap = arg;
1107 1132
1108 memset(cap,0,sizeof(*cap)); 1133 memset(cap,0,sizeof(*cap));
1109 strcpy(cap->driver, "cx8800"); 1134 strcpy(cap->driver, "cx8800");
1110 strlcpy(cap->card, cx88_boards[core->board].name, 1135 strlcpy(cap->card, cx88_boards[core->board].name,
1111 sizeof(cap->card)); 1136 sizeof(cap->card));
1112 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci)); 1137 sprintf(cap->bus_info,"PCI:%s",pci_name(dev->pci));
@@ -1116,12 +1141,128 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1116 V4L2_CAP_READWRITE | 1141 V4L2_CAP_READWRITE |
1117 V4L2_CAP_STREAMING | 1142 V4L2_CAP_STREAMING |
1118 V4L2_CAP_VBI_CAPTURE | 1143 V4L2_CAP_VBI_CAPTURE |
1144 V4L2_CAP_VIDEO_OVERLAY |
1119 0; 1145 0;
1120 if (UNSET != core->tuner_type) 1146 if (UNSET != core->tuner_type)
1121 cap->capabilities |= V4L2_CAP_TUNER; 1147 cap->capabilities |= V4L2_CAP_TUNER;
1122 return 0; 1148 return 0;
1123 } 1149 }
1124 1150
1151 /* --- capture ioctls ---------------------------------------- */
1152 case VIDIOC_ENUM_FMT:
1153 {
1154 struct v4l2_fmtdesc *f = arg;
1155 enum v4l2_buf_type type;
1156 unsigned int index;
1157
1158 index = f->index;
1159 type = f->type;
1160 switch (type) {
1161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1162 if (index >= ARRAY_SIZE(formats))
1163 return -EINVAL;
1164 memset(f,0,sizeof(*f));
1165 f->index = index;
1166 f->type = type;
1167 strlcpy(f->description,formats[index].name,sizeof(f->description));
1168 f->pixelformat = formats[index].fourcc;
1169 break;
1170 default:
1171 return -EINVAL;
1172 }
1173 return 0;
1174 }
1175 case VIDIOC_G_FMT:
1176 {
1177 struct v4l2_format *f = arg;
1178 return cx8800_g_fmt(dev,fh,f);
1179 }
1180 case VIDIOC_S_FMT:
1181 {
1182 struct v4l2_format *f = arg;
1183 return cx8800_s_fmt(dev,fh,f);
1184 }
1185 case VIDIOC_TRY_FMT:
1186 {
1187 struct v4l2_format *f = arg;
1188 return cx8800_try_fmt(dev,fh,f);
1189 }
1190
1191 /* --- streaming capture ------------------------------------- */
1192 case VIDIOCGMBUF:
1193 {
1194 struct video_mbuf *mbuf = arg;
1195 struct videobuf_queue *q;
1196 struct v4l2_requestbuffers req;
1197 unsigned int i;
1198
1199 q = get_queue(fh);
1200 memset(&req,0,sizeof(req));
1201 req.type = q->type;
1202 req.count = 8;
1203 req.memory = V4L2_MEMORY_MMAP;
1204 err = videobuf_reqbufs(q,&req);
1205 if (err < 0)
1206 return err;
1207 memset(mbuf,0,sizeof(*mbuf));
1208 mbuf->frames = req.count;
1209 mbuf->size = 0;
1210 for (i = 0; i < mbuf->frames; i++) {
1211 mbuf->offsets[i] = q->bufs[i]->boff;
1212 mbuf->size += q->bufs[i]->bsize;
1213 }
1214 return 0;
1215 }
1216 case VIDIOC_REQBUFS:
1217 return videobuf_reqbufs(get_queue(fh), arg);
1218
1219 case VIDIOC_QUERYBUF:
1220 return videobuf_querybuf(get_queue(fh), arg);
1221
1222 case VIDIOC_QBUF:
1223 return videobuf_qbuf(get_queue(fh), arg);
1224
1225 case VIDIOC_DQBUF:
1226 return videobuf_dqbuf(get_queue(fh), arg,
1227 file->f_flags & O_NONBLOCK);
1228
1229 case VIDIOC_STREAMON:
1230 {
1231 int res = get_ressource(fh);
1232
1233 if (!res_get(dev,fh,res))
1234 return -EBUSY;
1235 return videobuf_streamon(get_queue(fh));
1236 }
1237 case VIDIOC_STREAMOFF:
1238 {
1239 int res = get_ressource(fh);
1240
1241 err = videobuf_streamoff(get_queue(fh));
1242 if (err < 0)
1243 return err;
1244 res_free(dev,fh,res);
1245 return 0;
1246 }
1247
1248 default:
1249 return cx88_do_ioctl( inode, file, fh->radio, core, cmd, arg, video_do_ioctl );
1250 }
1251 return 0;
1252}
1253
1254int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
1255 struct cx88_core *core, unsigned int cmd, void *arg, v4l2_kioctl driver_ioctl)
1256{
1257 int err;
1258
1259 if (video_debug > 1)
1260 cx88_print_ioctl(core->name,cmd);
1261 printk( KERN_INFO "CORE IOCTL: 0x%x\n", cmd );
1262 cx88_print_ioctl(core->name,cmd);
1263 dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
1264
1265 switch (cmd) {
1125 /* ---------- tv norms ---------- */ 1266 /* ---------- tv norms ---------- */
1126 case VIDIOC_ENUMSTD: 1267 case VIDIOC_ENUMSTD:
1127 { 1268 {
@@ -1156,9 +1297,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1156 if (i == ARRAY_SIZE(tvnorms)) 1297 if (i == ARRAY_SIZE(tvnorms))
1157 return -EINVAL; 1298 return -EINVAL;
1158 1299
1159 down(&dev->lock); 1300 down(&core->lock);
1160 cx88_set_tvnorm(dev->core,&tvnorms[i]); 1301 cx88_set_tvnorm(core,&tvnorms[i]);
1161 up(&dev->lock); 1302 up(&core->lock);
1162 return 0; 1303 return 0;
1163 } 1304 }
1164 1305
@@ -1199,7 +1340,7 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1199 { 1340 {
1200 unsigned int *i = arg; 1341 unsigned int *i = arg;
1201 1342
1202 *i = dev->core->input; 1343 *i = core->input;
1203 return 0; 1344 return 0;
1204 } 1345 }
1205 case VIDIOC_S_INPUT: 1346 case VIDIOC_S_INPUT:
@@ -1208,55 +1349,15 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1208 1349
1209 if (*i >= 4) 1350 if (*i >= 4)
1210 return -EINVAL; 1351 return -EINVAL;
1211 down(&dev->lock); 1352 down(&core->lock);
1212 cx88_newstation(core); 1353 cx88_newstation(core);
1213 video_mux(dev,*i); 1354 video_mux(core,*i);
1214 up(&dev->lock); 1355 up(&core->lock);
1215 return 0; 1356 return 0;
1216 } 1357 }
1217 1358
1218 1359
1219 1360
1220 /* --- capture ioctls ---------------------------------------- */
1221 case VIDIOC_ENUM_FMT:
1222 {
1223 struct v4l2_fmtdesc *f = arg;
1224 enum v4l2_buf_type type;
1225 unsigned int index;
1226
1227 index = f->index;
1228 type = f->type;
1229 switch (type) {
1230 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1231 if (index >= ARRAY_SIZE(formats))
1232 return -EINVAL;
1233 memset(f,0,sizeof(*f));
1234 f->index = index;
1235 f->type = type;
1236 strlcpy(f->description,formats[index].name,sizeof(f->description));
1237 f->pixelformat = formats[index].fourcc;
1238 break;
1239 default:
1240 return -EINVAL;
1241 }
1242 return 0;
1243 }
1244 case VIDIOC_G_FMT:
1245 {
1246 struct v4l2_format *f = arg;
1247 return cx8800_g_fmt(dev,fh,f);
1248 }
1249 case VIDIOC_S_FMT:
1250 {
1251 struct v4l2_format *f = arg;
1252 return cx8800_s_fmt(dev,fh,f);
1253 }
1254 case VIDIOC_TRY_FMT:
1255 {
1256 struct v4l2_format *f = arg;
1257 return cx8800_try_fmt(dev,fh,f);
1258 }
1259
1260 /* --- controls ---------------------------------------------- */ 1361 /* --- controls ---------------------------------------------- */
1261 case VIDIOC_QUERYCTRL: 1362 case VIDIOC_QUERYCTRL:
1262 { 1363 {
@@ -1277,9 +1378,9 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1277 return 0; 1378 return 0;
1278 } 1379 }
1279 case VIDIOC_G_CTRL: 1380 case VIDIOC_G_CTRL:
1280 return get_control(dev,arg); 1381 return get_control(core,arg);
1281 case VIDIOC_S_CTRL: 1382 case VIDIOC_S_CTRL:
1282 return set_control(dev,arg); 1383 return set_control(core,arg);
1283 1384
1284 /* --- tuner ioctls ------------------------------------------ */ 1385 /* --- tuner ioctls ------------------------------------------ */
1285 case VIDIOC_G_TUNER: 1386 case VIDIOC_G_TUNER:
@@ -1323,10 +1424,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1323 if (UNSET == core->tuner_type) 1424 if (UNSET == core->tuner_type)
1324 return -EINVAL; 1425 return -EINVAL;
1325 1426
1326 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; 1427 /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */
1327 f->frequency = dev->freq; 1428 f->type = radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1429 f->frequency = core->freq;
1328 1430
1329 cx88_call_i2c_clients(dev->core,VIDIOC_G_FREQUENCY,f); 1431 cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f);
1330 1432
1331 return 0; 1433 return 0;
1332 } 1434 }
@@ -1338,83 +1440,26 @@ static int video_do_ioctl(struct inode *inode, struct file *file,
1338 return -EINVAL; 1440 return -EINVAL;
1339 if (f->tuner != 0) 1441 if (f->tuner != 0)
1340 return -EINVAL; 1442 return -EINVAL;
1341 if (0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV) 1443 if (0 == radio && f->type != V4L2_TUNER_ANALOG_TV)
1342 return -EINVAL; 1444 return -EINVAL;
1343 if (1 == fh->radio && f->type != V4L2_TUNER_RADIO) 1445 if (1 == radio && f->type != V4L2_TUNER_RADIO)
1344 return -EINVAL; 1446 return -EINVAL;
1345 down(&dev->lock); 1447 down(&core->lock);
1346 dev->freq = f->frequency; 1448 core->freq = f->frequency;
1347 cx88_newstation(core); 1449 cx88_newstation(core);
1348 cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f); 1450 cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f);
1349 1451
1350 /* When changing channels it is required to reset TVAUDIO */ 1452 /* When changing channels it is required to reset TVAUDIO */
1351 msleep (10); 1453 msleep (10);
1352 cx88_set_tvaudio(core); 1454 cx88_set_tvaudio(core);
1353 1455
1354 up(&dev->lock); 1456 up(&core->lock);
1355 return 0;
1356 }
1357
1358 /* --- streaming capture ------------------------------------- */
1359 case VIDIOCGMBUF:
1360 {
1361 struct video_mbuf *mbuf = arg;
1362 struct videobuf_queue *q;
1363 struct v4l2_requestbuffers req;
1364 unsigned int i;
1365
1366 q = get_queue(fh);
1367 memset(&req,0,sizeof(req));
1368 req.type = q->type;
1369 req.count = 8;
1370 req.memory = V4L2_MEMORY_MMAP;
1371 err = videobuf_reqbufs(q,&req);
1372 if (err < 0)
1373 return err;
1374 memset(mbuf,0,sizeof(*mbuf));
1375 mbuf->frames = req.count;
1376 mbuf->size = 0;
1377 for (i = 0; i < mbuf->frames; i++) {
1378 mbuf->offsets[i] = q->bufs[i]->boff;
1379 mbuf->size += q->bufs[i]->bsize;
1380 }
1381 return 0;
1382 }
1383 case VIDIOC_REQBUFS:
1384 return videobuf_reqbufs(get_queue(fh), arg);
1385
1386 case VIDIOC_QUERYBUF:
1387 return videobuf_querybuf(get_queue(fh), arg);
1388
1389 case VIDIOC_QBUF:
1390 return videobuf_qbuf(get_queue(fh), arg);
1391
1392 case VIDIOC_DQBUF:
1393 return videobuf_dqbuf(get_queue(fh), arg,
1394 file->f_flags & O_NONBLOCK);
1395
1396 case VIDIOC_STREAMON:
1397 {
1398 int res = get_ressource(fh);
1399
1400 if (!res_get(dev,fh,res))
1401 return -EBUSY;
1402 return videobuf_streamon(get_queue(fh));
1403 }
1404 case VIDIOC_STREAMOFF:
1405 {
1406 int res = get_ressource(fh);
1407
1408 err = videobuf_streamoff(get_queue(fh));
1409 if (err < 0)
1410 return err;
1411 res_free(dev,fh,res);
1412 return 0; 1457 return 0;
1413 } 1458 }
1414 1459
1415 default: 1460 default:
1416 return v4l_compat_translate_ioctl(inode,file,cmd,arg, 1461 return v4l_compat_translate_ioctl(inode,file,cmd,arg,
1417 video_do_ioctl); 1462 driver_ioctl);
1418 } 1463 }
1419 return 0; 1464 return 0;
1420} 1465}
@@ -1461,7 +1506,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1461 memset(t,0,sizeof(*t)); 1506 memset(t,0,sizeof(*t));
1462 strcpy(t->name, "Radio"); 1507 strcpy(t->name, "Radio");
1463 1508
1464 cx88_call_i2c_clients(dev->core,VIDIOC_G_TUNER,t); 1509 cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t);
1465 return 0; 1510 return 0;
1466 } 1511 }
1467 case VIDIOC_ENUMINPUT: 1512 case VIDIOC_ENUMINPUT:
@@ -1501,8 +1546,8 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1501 if (v->tuner) /* Only tuner 0 */ 1546 if (v->tuner) /* Only tuner 0 */
1502 return -EINVAL; 1547 return -EINVAL;
1503 1548
1504 cx88_call_i2c_clients(dev->core,VIDIOCSTUNER,v); 1549 cx88_call_i2c_clients(core,VIDIOCSTUNER,v);
1505 return 0; 1550 return 0;
1506 } 1551 }
1507 case VIDIOC_S_TUNER: 1552 case VIDIOC_S_TUNER:
1508 { 1553 {
@@ -1511,7 +1556,7 @@ static int radio_do_ioctl(struct inode *inode, struct file *file,
1511 if (0 != t->index) 1556 if (0 != t->index)
1512 return -EINVAL; 1557 return -EINVAL;
1513 1558
1514 cx88_call_i2c_clients(dev->core,VIDIOC_S_TUNER,t); 1559 cx88_call_i2c_clients(core,VIDIOC_S_TUNER,t);
1515 1560
1516 return 0; 1561 return 0;
1517 } 1562 }
@@ -1569,7 +1614,7 @@ static void cx8800_vid_timeout(unsigned long data)
1569 struct cx88_buffer *buf; 1614 struct cx88_buffer *buf;
1570 unsigned long flags; 1615 unsigned long flags;
1571 1616
1572 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]); 1617 cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]);
1573 1618
1574 cx_clear(MO_VID_DMACNTRL, 0x11); 1619 cx_clear(MO_VID_DMACNTRL, 0x11);
1575 cx_clear(VID_CAPTURE_CONTROL, 0x06); 1620 cx_clear(VID_CAPTURE_CONTROL, 0x06);
@@ -1614,14 +1659,14 @@ static void cx8800_vid_irq(struct cx8800_dev *dev)
1614 printk(KERN_WARNING "%s/0: video risc op code error\n",core->name); 1659 printk(KERN_WARNING "%s/0: video risc op code error\n",core->name);
1615 cx_clear(MO_VID_DMACNTRL, 0x11); 1660 cx_clear(MO_VID_DMACNTRL, 0x11);
1616 cx_clear(VID_CAPTURE_CONTROL, 0x06); 1661 cx_clear(VID_CAPTURE_CONTROL, 0x06);
1617 cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH21]); 1662 cx88_sram_channel_dump(core, &cx88_sram_channels[SRAM_CH21]);
1618 } 1663 }
1619 1664
1620 /* risc1 y */ 1665 /* risc1 y */
1621 if (status & 0x01) { 1666 if (status & 0x01) {
1622 spin_lock(&dev->slock); 1667 spin_lock(&dev->slock);
1623 count = cx_read(MO_VIDY_GPCNT); 1668 count = cx_read(MO_VIDY_GPCNT);
1624 cx88_wakeup(dev->core, &dev->vidq, count); 1669 cx88_wakeup(core, &dev->vidq, count);
1625 spin_unlock(&dev->slock); 1670 spin_unlock(&dev->slock);
1626 } 1671 }
1627 1672
@@ -1629,7 +1674,7 @@ static void cx8800_vid_irq(struct cx8800_dev *dev)
1629 if (status & 0x08) { 1674 if (status & 0x08) {
1630 spin_lock(&dev->slock); 1675 spin_lock(&dev->slock);
1631 count = cx_read(MO_VBI_GPCNT); 1676 count = cx_read(MO_VBI_GPCNT);
1632 cx88_wakeup(dev->core, &dev->vbiq, count); 1677 cx88_wakeup(core, &dev->vbiq, count);
1633 spin_unlock(&dev->slock); 1678 spin_unlock(&dev->slock);
1634 } 1679 }
1635 1680
@@ -1798,7 +1843,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1798 } 1843 }
1799 1844
1800 /* initialize driver struct */ 1845 /* initialize driver struct */
1801 init_MUTEX(&dev->lock);
1802 spin_lock_init(&dev->slock); 1846 spin_lock_init(&dev->slock);
1803 core->tvnorm = tvnorms; 1847 core->tvnorm = tvnorms;
1804 1848
@@ -1835,6 +1879,7 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1835 request_module("tuner"); 1879 request_module("tuner");
1836 if (core->tda9887_conf) 1880 if (core->tda9887_conf)
1837 request_module("tda9887"); 1881 request_module("tda9887");
1882
1838 /* register v4l devices */ 1883 /* register v4l devices */
1839 dev->video_dev = cx88_vdev_init(core,dev->pci, 1884 dev->video_dev = cx88_vdev_init(core,dev->pci,
1840 &cx8800_video_template,"video"); 1885 &cx8800_video_template,"video");
@@ -1878,11 +1923,11 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1878 pci_set_drvdata(pci_dev,dev); 1923 pci_set_drvdata(pci_dev,dev);
1879 1924
1880 /* initial device configuration */ 1925 /* initial device configuration */
1881 down(&dev->lock); 1926 down(&core->lock);
1882 init_controls(dev); 1927 init_controls(core);
1883 cx88_set_tvnorm(dev->core,tvnorms); 1928 cx88_set_tvnorm(core,tvnorms);
1884 video_mux(dev,0); 1929 video_mux(core,0);
1885 up(&dev->lock); 1930 up(&core->lock);
1886 1931
1887 /* start tvaudio thread */ 1932 /* start tvaudio thread */
1888 if (core->tuner_type != TUNER_ABSENT) 1933 if (core->tuner_type != TUNER_ABSENT)
@@ -1902,14 +1947,15 @@ fail_free:
1902static void __devexit cx8800_finidev(struct pci_dev *pci_dev) 1947static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
1903{ 1948{
1904 struct cx8800_dev *dev = pci_get_drvdata(pci_dev); 1949 struct cx8800_dev *dev = pci_get_drvdata(pci_dev);
1950 struct cx88_core *core = dev->core;
1905 1951
1906 /* stop thread */ 1952 /* stop thread */
1907 if (dev->core->kthread) { 1953 if (core->kthread) {
1908 kthread_stop(dev->core->kthread); 1954 kthread_stop(core->kthread);
1909 dev->core->kthread = NULL; 1955 core->kthread = NULL;
1910 } 1956 }
1911 1957
1912 cx88_shutdown(dev->core); /* FIXME */ 1958 cx88_shutdown(core); /* FIXME */
1913 pci_disable_device(pci_dev); 1959 pci_disable_device(pci_dev);
1914 1960
1915 /* unregister stuff */ 1961 /* unregister stuff */
@@ -1921,7 +1967,7 @@ static void __devexit cx8800_finidev(struct pci_dev *pci_dev)
1921 /* free memory */ 1967 /* free memory */
1922 btcx_riscmem_free(dev->pci,&dev->vidq.stopper); 1968 btcx_riscmem_free(dev->pci,&dev->vidq.stopper);
1923 list_del(&dev->devlist); 1969 list_del(&dev->devlist);
1924 cx88_core_put(dev->core,dev->pci); 1970 cx88_core_put(core,dev->pci);
1925 kfree(dev); 1971 kfree(dev);
1926} 1972}
1927 1973
@@ -1945,7 +1991,7 @@ static int cx8800_suspend(struct pci_dev *pci_dev, pm_message_t state)
1945 spin_unlock(&dev->slock); 1991 spin_unlock(&dev->slock);
1946 1992
1947 /* FIXME -- shutdown device */ 1993 /* FIXME -- shutdown device */
1948 cx88_shutdown(dev->core); 1994 cx88_shutdown(core);
1949 1995
1950 pci_save_state(pci_dev); 1996 pci_save_state(pci_dev);
1951 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) { 1997 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
@@ -1968,7 +2014,7 @@ static int cx8800_resume(struct pci_dev *pci_dev)
1968 pci_restore_state(pci_dev); 2014 pci_restore_state(pci_dev);
1969 2015
1970 /* FIXME: re-initialize hardware */ 2016 /* FIXME: re-initialize hardware */
1971 cx88_reset(dev->core); 2017 cx88_reset(core);
1972 2018
1973 /* restart video+vbi capture */ 2019 /* restart video+vbi capture */
1974 spin_lock(&dev->slock); 2020 spin_lock(&dev->slock);
@@ -2030,6 +2076,8 @@ static void cx8800_fini(void)
2030module_init(cx8800_init); 2076module_init(cx8800_init);
2031module_exit(cx8800_fini); 2077module_exit(cx8800_fini);
2032 2078
2079EXPORT_SYMBOL(cx88_do_ioctl);
2080
2033/* ----------------------------------------------------------- */ 2081/* ----------------------------------------------------------- */
2034/* 2082/*
2035 * Local variables: 2083 * Local variables:
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index da65dc92787..13b8fb7e921 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -1,5 +1,4 @@
1/* 1/*
2 * $Id: cx88.h,v 1.70 2005/07/24 17:44:09 mkrufky Exp $
3 * 2 *
4 * v4l2 device driver for cx2388x based TV cards 3 * v4l2 device driver for cx2388x based TV cards
5 * 4 *
@@ -48,6 +47,9 @@
48 47
49#define CX88_MAXBOARDS 8 48#define CX88_MAXBOARDS 8
50 49
50/* Max number of inputs by card */
51#define MAX_CX88_INPUT 8
52
51/* ----------------------------------------------------------- */ 53/* ----------------------------------------------------------- */
52/* defines and enums */ 54/* defines and enums */
53 55
@@ -199,7 +201,7 @@ struct cx88_board {
199 unsigned char tuner_addr; 201 unsigned char tuner_addr;
200 unsigned char radio_addr; 202 unsigned char radio_addr;
201 int tda9887_conf; 203 int tda9887_conf;
202 struct cx88_input input[8]; 204 struct cx88_input input[MAX_CX88_INPUT];
203 struct cx88_input radio; 205 struct cx88_input radio;
204 int blackbird:1; 206 int blackbird:1;
205 int dvb:1; 207 int dvb:1;
@@ -288,6 +290,11 @@ struct cx88_core {
288 290
289 /* IR remote control state */ 291 /* IR remote control state */
290 struct cx88_IR *ir; 292 struct cx88_IR *ir;
293
294 struct semaphore lock;
295
296 /* various v4l controls */
297 u32 freq;
291}; 298};
292 299
293struct cx8800_dev; 300struct cx8800_dev;
@@ -323,8 +330,7 @@ struct cx8800_suspend_state {
323struct cx8800_dev { 330struct cx8800_dev {
324 struct cx88_core *core; 331 struct cx88_core *core;
325 struct list_head devlist; 332 struct list_head devlist;
326 struct semaphore lock; 333 spinlock_t slock;
327 spinlock_t slock;
328 334
329 /* various device info */ 335 /* various device info */
330 unsigned int resources; 336 unsigned int resources;
@@ -342,7 +348,6 @@ struct cx8800_dev {
342 struct cx88_dmaqueue vbiq; 348 struct cx88_dmaqueue vbiq;
343 349
344 /* various v4l controls */ 350 /* various v4l controls */
345 u32 freq;
346 351
347 /* other global state info */ 352 /* other global state info */
348 struct cx8800_suspend_state state; 353 struct cx8800_suspend_state state;
@@ -350,14 +355,8 @@ struct cx8800_dev {
350 355
351/* ----------------------------------------------------------- */ 356/* ----------------------------------------------------------- */
352/* function 1: audio/alsa stuff */ 357/* function 1: audio/alsa stuff */
358/* =============> moved to cx88-alsa.c <====================== */
353 359
354struct cx8801_dev {
355 struct cx88_core *core;
356
357 /* pci i/o */
358 struct pci_dev *pci;
359 unsigned char pci_rev,pci_lat;
360};
361 360
362/* ----------------------------------------------------------- */ 361/* ----------------------------------------------------------- */
363/* function 2: mpeg stuff */ 362/* function 2: mpeg stuff */
@@ -373,8 +372,7 @@ struct cx8802_suspend_state {
373 372
374struct cx8802_dev { 373struct cx8802_dev {
375 struct cx88_core *core; 374 struct cx88_core *core;
376 struct semaphore lock; 375 spinlock_t slock;
377 spinlock_t slock;
378 376
379 /* pci i/o */ 377 /* pci i/o */
380 struct pci_dev *pci; 378 struct pci_dev *pci;
@@ -553,8 +551,21 @@ void cx8802_fini_common(struct cx8802_dev *dev);
553int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state); 551int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state);
554int cx8802_resume_common(struct pci_dev *pci_dev); 552int cx8802_resume_common(struct pci_dev *pci_dev);
555 553
554/* ----------------------------------------------------------- */
555/* cx88-video.c */
556extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
557 struct cx88_core *core, unsigned int cmd,
558 void *arg, v4l2_kioctl driver_ioctl);
559
560/* ----------------------------------------------------------- */
561/* cx88-blackbird.c */
562extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
563 unsigned int cmd, void *arg);
564extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
565
556/* 566/*
557 * Local variables: 567 * Local variables:
558 * c-basic-offset: 8 568 * c-basic-offset: 8
559 * End: 569 * End:
570 * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off
560 */ 571 */