diff options
author | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 2005-09-09 16:03:41 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-09 16:57:49 -0400 |
commit | e52e98a7eccfb0e7e91630d01690fb11d77db77d (patch) | |
tree | d910e743159977ee695c40b795a4b84d43a4dbcb /drivers/media/video | |
parent | 24a70fdce872d70171b1f49dcd1a7c3a4e8396b2 (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/video')
-rw-r--r-- | drivers/media/video/cx88/cx88-blackbird.c | 73 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-cards.c | 24 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-core.c | 21 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-dvb.c | 47 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-i2c.c | 1 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-input.c | 96 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-mpeg.c | 17 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-reg.h | 24 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-tvaudio.c | 742 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-vbi.c | 1 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-video.c | 388 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88.h | 39 |
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 4f39688f780a..0c0c59e94774 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 | ||
994 | int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, | ||
995 | unsigned int cmd, void *arg); | ||
996 | unsigned int (*cx88_ioctl_translator)(unsigned int cmd); | ||
997 | |||
998 | static unsigned int mpeg_translate_ioctl(unsigned int cmd) | ||
999 | { | ||
1000 | return cmd; | ||
1001 | } | ||
1002 | |||
967 | static int mpeg_ioctl(struct inode *inode, struct file *file, | 1003 | static 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 | ||
973 | static int mpeg_open(struct inode *inode, struct file *file) | 1010 | static 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) | |||
1213 | module_init(blackbird_init); | 1255 | module_init(blackbird_init); |
1214 | module_exit(blackbird_fini); | 1256 | module_exit(blackbird_fini); |
1215 | 1257 | ||
1258 | EXPORT_SYMBOL(cx88_ioctl_hook); | ||
1259 | EXPORT_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 ebf02a7f81e8..92623231db78 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 | }; |
784 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); | 780 | const 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 5e868f5cd0c0..dc5c5c1f3461 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 78d223257a68..cc71cafc2cbd 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 = { | |||
210 | static int lgdt330x_pll_set(struct dvb_frontend* fe, | 210 | static 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 | |||
282 | static 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 | ||
266 | static int dvb_register(struct cx8802_dev *dev) | 291 | static 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 7f598039e025..761cebd40dbd 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 214887798192..d7980c51478d 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 */ | ||
215 | static 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 | |||
215 | struct cx88_IR { | 261 | struct 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] */ | |||
241 | MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | 287 | MODULE_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) | |||
445 | void cx88_ir_irq(struct cx88_core *core) | 496 | void 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 fe2767c0ff94..6d0d15c3a1c6 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 37f82662d265..0a3a62fc9bbb 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 91207f10bae7..2765acee0285 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 | ||
123 | static void set_audio_start(struct cx88_core *core, | 122 | static 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 | ||
142 | static void set_audio_finish(struct cx88_core *core) | 135 | static 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 | ||
172 | static void set_audio_standard_BTSC(struct cx88_core *core, unsigned int sap) | 165 | static 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 | ||
282 | static void set_audio_standard_NICAM_L(struct cx88_core *core, int stereo) | 275 | static 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 | ||
407 | static void set_audio_standard_PAL_I(struct cx88_core *core, int stereo) | 399 | static 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 | ||
520 | static void set_audio_standard_A2(struct cx88_core *core) | 513 | static 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 | ||
629 | static void set_audio_standard_EIAJ(struct cx88_core *core) | 652 | static 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 | ||
643 | static void set_audio_standard_FM(struct cx88_core *core, enum cx88_deemph_type deemph) | 666 | static 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 320d57888bbd..9bc6c8995581 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 5f58c103198a..61d4b29ec302 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); | |||
66 | MODULE_PARM_DESC(vid_limit,"capture memory limit in megabytes"); | 65 | MODULE_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 | ||
327 | static int res_get(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bit) | 326 | static 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) | |||
360 | static | 360 | static |
361 | void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits) | 361 | void 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 | ||
375 | static int video_mux(struct cx8800_dev *dev, unsigned int input) | 376 | /* static int video_mux(struct cx8800_dev *dev, unsigned int input) */ |
377 | static 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) | |||
455 | static int restart_video_queue(struct cx8800_dev *dev, | 465 | static 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 | ||
873 | static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) | 891 | /* static int get_control(struct cx8800_dev *dev, struct v4l2_control *ctl) */ |
892 | static 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 | ||
901 | static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) | 920 | /* static int set_control(struct cx8800_dev *dev, struct v4l2_control *ctl) */ |
921 | static 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 | ||
949 | static void init_controls(struct cx8800_dev *dev) | 969 | /* static void init_controls(struct cx8800_dev *dev) */ |
970 | static 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, | |||
1004 | static int cx8800_try_fmt(struct cx8800_dev *dev, struct cx8800_fh *fh, | 1025 | static 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 | |||
1254 | int 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: | |||
1902 | static void __devexit cx8800_finidev(struct pci_dev *pci_dev) | 1947 | static 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) | |||
2030 | module_init(cx8800_init); | 2076 | module_init(cx8800_init); |
2031 | module_exit(cx8800_fini); | 2077 | module_exit(cx8800_fini); |
2032 | 2078 | ||
2079 | EXPORT_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 da65dc92787c..13b8fb7e921a 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 | ||
293 | struct cx8800_dev; | 300 | struct cx8800_dev; |
@@ -323,8 +330,7 @@ struct cx8800_suspend_state { | |||
323 | struct cx8800_dev { | 330 | struct 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 | ||
354 | struct 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 | ||
374 | struct cx8802_dev { | 373 | struct 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); | |||
553 | int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state); | 551 | int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state); |
554 | int cx8802_resume_common(struct pci_dev *pci_dev); | 552 | int cx8802_resume_common(struct pci_dev *pci_dev); |
555 | 553 | ||
554 | /* ----------------------------------------------------------- */ | ||
555 | /* cx88-video.c */ | ||
556 | extern 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 */ | ||
562 | extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, | ||
563 | unsigned int cmd, void *arg); | ||
564 | extern 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 | */ |