diff options
Diffstat (limited to 'drivers/media/video/cx88')
-rw-r--r-- | drivers/media/video/cx88/Kconfig | 1 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-blackbird.c | 179 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-cards.c | 86 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-dvb.c | 333 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-input.c | 77 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-mpeg.c | 348 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-tvaudio.c | 13 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-video.c | 32 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88.h | 47 |
9 files changed, 754 insertions, 362 deletions
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig index 0f9d96963618..b2a66ba625f9 100644 --- a/drivers/media/video/cx88/Kconfig +++ b/drivers/media/video/cx88/Kconfig | |||
@@ -53,6 +53,7 @@ config VIDEO_CX88_DVB | |||
53 | select DVB_OR51132 if !DVB_FE_CUSTOMISE | 53 | select DVB_OR51132 if !DVB_FE_CUSTOMISE |
54 | select DVB_CX22702 if !DVB_FE_CUSTOMISE | 54 | select DVB_CX22702 if !DVB_FE_CUSTOMISE |
55 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | 55 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE |
56 | select DVB_TUNER_LGH06XF if !DVB_FE_CUSTOMISE | ||
56 | select DVB_NXT200X if !DVB_FE_CUSTOMISE | 57 | select DVB_NXT200X if !DVB_FE_CUSTOMISE |
57 | select DVB_CX24123 if !DVB_FE_CUSTOMISE | 58 | select DVB_CX24123 if !DVB_FE_CUSTOMISE |
58 | select DVB_ISL6421 if !DVB_FE_CUSTOMISE | 59 | select DVB_ISL6421 if !DVB_FE_CUSTOMISE |
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c index 46738321adaf..0cf0360588e6 100644 --- a/drivers/media/video/cx88/cx88-blackbird.c +++ b/drivers/media/video/cx88/cx88-blackbird.c | |||
@@ -50,7 +50,6 @@ MODULE_PARM_DESC(debug,"enable debug messages [blackbird]"); | |||
50 | #define dprintk(level,fmt, arg...) if (debug >= level) \ | 50 | #define dprintk(level,fmt, arg...) if (debug >= level) \ |
51 | printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg) | 51 | printk(KERN_DEBUG "%s/2-bb: " fmt, dev->core->name , ## arg) |
52 | 52 | ||
53 | static LIST_HEAD(cx8802_devlist); | ||
54 | 53 | ||
55 | /* ------------------------------------------------------------------ */ | 54 | /* ------------------------------------------------------------------ */ |
56 | 55 | ||
@@ -882,7 +881,7 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, | |||
882 | BLACKBIRD_MPEG_CAPTURE, | 881 | BLACKBIRD_MPEG_CAPTURE, |
883 | BLACKBIRD_RAW_BITS_NONE); | 882 | BLACKBIRD_RAW_BITS_NONE); |
884 | 883 | ||
885 | cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl); | 884 | cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook); |
886 | 885 | ||
887 | blackbird_initialize_codec(dev); | 886 | blackbird_initialize_codec(dev); |
888 | cx88_set_scale(dev->core, dev->width, dev->height, | 887 | cx88_set_scale(dev->core, dev->width, dev->height, |
@@ -914,11 +913,15 @@ static int mpeg_do_ioctl(struct inode *inode, struct file *file, | |||
914 | } | 913 | } |
915 | 914 | ||
916 | default: | 915 | default: |
917 | return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, mpeg_do_ioctl); | 916 | return cx88_do_ioctl(inode, file, 0, dev->core, cmd, arg, cx88_ioctl_hook); |
918 | } | 917 | } |
919 | return 0; | 918 | return 0; |
920 | } | 919 | } |
921 | 920 | ||
921 | int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, | ||
922 | unsigned int cmd, void *arg); | ||
923 | unsigned int (*cx88_ioctl_translator)(unsigned int cmd); | ||
924 | |||
922 | static unsigned int mpeg_translate_ioctl(unsigned int cmd) | 925 | static unsigned int mpeg_translate_ioctl(unsigned int cmd) |
923 | { | 926 | { |
924 | return cmd; | 927 | return cmd; |
@@ -927,33 +930,49 @@ static unsigned int mpeg_translate_ioctl(unsigned int cmd) | |||
927 | static int mpeg_ioctl(struct inode *inode, struct file *file, | 930 | static int mpeg_ioctl(struct inode *inode, struct file *file, |
928 | unsigned int cmd, unsigned long arg) | 931 | unsigned int cmd, unsigned long arg) |
929 | { | 932 | { |
930 | cmd = mpeg_translate_ioctl( cmd ); | 933 | cmd = cx88_ioctl_translator( cmd ); |
931 | return video_usercopy(inode, file, cmd, arg, mpeg_do_ioctl); | 934 | return video_usercopy(inode, file, cmd, arg, cx88_ioctl_hook); |
932 | } | 935 | } |
933 | 936 | ||
934 | static int mpeg_open(struct inode *inode, struct file *file) | 937 | static int mpeg_open(struct inode *inode, struct file *file) |
935 | { | 938 | { |
936 | int minor = iminor(inode); | 939 | int minor = iminor(inode); |
937 | struct cx8802_dev *h,*dev = NULL; | 940 | struct cx8802_dev *dev = NULL; |
938 | struct cx8802_fh *fh; | 941 | struct cx8802_fh *fh; |
939 | struct list_head *list; | 942 | struct cx8802_driver *drv = NULL; |
943 | int err; | ||
940 | 944 | ||
941 | list_for_each(list,&cx8802_devlist) { | 945 | dev = cx8802_get_device(inode); |
942 | h = list_entry(list, struct cx8802_dev, devlist); | 946 | |
943 | if (h->mpeg_dev->minor == minor) | 947 | dprintk( 1, "%s\n", __FUNCTION__); |
944 | dev = h; | 948 | |
945 | } | 949 | if (dev == NULL) |
946 | if (NULL == dev) | ||
947 | return -ENODEV; | 950 | return -ENODEV; |
948 | 951 | ||
949 | if (blackbird_initialize_codec(dev) < 0) | 952 | /* Make sure we can acquire the hardware */ |
953 | drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); | ||
954 | if (drv) { | ||
955 | err = drv->request_acquire(drv); | ||
956 | if(err != 0) { | ||
957 | dprintk(1,"%s: Unable to acquire hardware, %d\n", __FUNCTION__, err); | ||
958 | return err; | ||
959 | } | ||
960 | } | ||
961 | |||
962 | if (blackbird_initialize_codec(dev) < 0) { | ||
963 | if (drv) | ||
964 | drv->request_release(drv); | ||
950 | return -EINVAL; | 965 | return -EINVAL; |
966 | } | ||
951 | dprintk(1,"open minor=%d\n",minor); | 967 | dprintk(1,"open minor=%d\n",minor); |
952 | 968 | ||
953 | /* allocate + initialize per filehandle data */ | 969 | /* allocate + initialize per filehandle data */ |
954 | fh = kzalloc(sizeof(*fh),GFP_KERNEL); | 970 | fh = kzalloc(sizeof(*fh),GFP_KERNEL); |
955 | if (NULL == fh) | 971 | if (NULL == fh) { |
972 | if (drv) | ||
973 | drv->request_release(drv); | ||
956 | return -ENOMEM; | 974 | return -ENOMEM; |
975 | } | ||
957 | file->private_data = fh; | 976 | file->private_data = fh; |
958 | fh->dev = dev; | 977 | fh->dev = dev; |
959 | 978 | ||
@@ -974,6 +993,8 @@ static int mpeg_open(struct inode *inode, struct file *file) | |||
974 | static int mpeg_release(struct inode *inode, struct file *file) | 993 | static int mpeg_release(struct inode *inode, struct file *file) |
975 | { | 994 | { |
976 | struct cx8802_fh *fh = file->private_data; | 995 | struct cx8802_fh *fh = file->private_data; |
996 | struct cx8802_dev *dev = NULL; | ||
997 | struct cx8802_driver *drv = NULL; | ||
977 | 998 | ||
978 | /* blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */ | 999 | /* blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */ |
979 | blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, | 1000 | blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, |
@@ -992,6 +1013,16 @@ static int mpeg_release(struct inode *inode, struct file *file) | |||
992 | videobuf_mmap_free(&fh->mpegq); | 1013 | videobuf_mmap_free(&fh->mpegq); |
993 | file->private_data = NULL; | 1014 | file->private_data = NULL; |
994 | kfree(fh); | 1015 | kfree(fh); |
1016 | |||
1017 | /* Make sure we release the hardware */ | ||
1018 | dev = cx8802_get_device(inode); | ||
1019 | if (dev == NULL) | ||
1020 | return -ENODEV; | ||
1021 | |||
1022 | drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD); | ||
1023 | if (drv) | ||
1024 | drv->request_release(drv); | ||
1025 | |||
995 | return 0; | 1026 | return 0; |
996 | } | 1027 | } |
997 | 1028 | ||
@@ -1043,6 +1074,44 @@ static struct video_device cx8802_mpeg_template = | |||
1043 | 1074 | ||
1044 | /* ------------------------------------------------------------------ */ | 1075 | /* ------------------------------------------------------------------ */ |
1045 | 1076 | ||
1077 | /* The CX8802 MPEG API will call this when we can use the hardware */ | ||
1078 | static int cx8802_blackbird_advise_acquire(struct cx8802_driver *drv) | ||
1079 | { | ||
1080 | struct cx88_core *core = drv->core; | ||
1081 | int err = 0; | ||
1082 | |||
1083 | switch (core->board) { | ||
1084 | case CX88_BOARD_HAUPPAUGE_HVR1300: | ||
1085 | /* By default, core setup will leave the cx22702 out of reset, on the bus. | ||
1086 | * We left the hardware on power up with the cx22702 active. | ||
1087 | * We're being given access to re-arrange the GPIOs. | ||
1088 | * Take the bus off the cx22702 and put the cx23416 on it. | ||
1089 | */ | ||
1090 | cx_clear(MO_GP0_IO, 0x00000080); /* cx22702 in reset */ | ||
1091 | cx_set(MO_GP0_IO, 0x00000004); /* Disable the cx22702 */ | ||
1092 | break; | ||
1093 | default: | ||
1094 | err = -ENODEV; | ||
1095 | } | ||
1096 | return err; | ||
1097 | } | ||
1098 | |||
1099 | /* The CX8802 MPEG API will call this when we need to release the hardware */ | ||
1100 | static int cx8802_blackbird_advise_release(struct cx8802_driver *drv) | ||
1101 | { | ||
1102 | struct cx88_core *core = drv->core; | ||
1103 | int err = 0; | ||
1104 | |||
1105 | switch (core->board) { | ||
1106 | case CX88_BOARD_HAUPPAUGE_HVR1300: | ||
1107 | /* Exit leaving the cx23416 on the bus */ | ||
1108 | break; | ||
1109 | default: | ||
1110 | err = -ENODEV; | ||
1111 | } | ||
1112 | return err; | ||
1113 | } | ||
1114 | |||
1046 | static void blackbird_unregister_video(struct cx8802_dev *dev) | 1115 | static void blackbird_unregister_video(struct cx8802_dev *dev) |
1047 | { | 1116 | { |
1048 | if (dev->mpeg_dev) { | 1117 | if (dev->mpeg_dev) { |
@@ -1073,28 +1142,23 @@ static int blackbird_register_video(struct cx8802_dev *dev) | |||
1073 | 1142 | ||
1074 | /* ----------------------------------------------------------- */ | 1143 | /* ----------------------------------------------------------- */ |
1075 | 1144 | ||
1076 | static int __devinit blackbird_probe(struct pci_dev *pci_dev, | 1145 | static int cx8802_blackbird_probe(struct cx8802_driver *drv) |
1077 | const struct pci_device_id *pci_id) | ||
1078 | { | 1146 | { |
1079 | struct cx8802_dev *dev; | 1147 | struct cx88_core *core = drv->core; |
1080 | struct cx88_core *core; | 1148 | struct cx8802_dev *dev = core->dvbdev; |
1081 | int err; | 1149 | int err; |
1082 | 1150 | ||
1083 | /* general setup */ | 1151 | dprintk( 1, "%s\n", __FUNCTION__); |
1084 | core = cx88_core_get(pci_dev); | 1152 | dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", |
1085 | if (NULL == core) | 1153 | core->board, |
1086 | return -EINVAL; | 1154 | core->name, |
1155 | core->pci_bus, | ||
1156 | core->pci_slot); | ||
1087 | 1157 | ||
1088 | err = -ENODEV; | 1158 | err = -ENODEV; |
1089 | if (!(cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD)) | 1159 | if (!(cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD)) |
1090 | goto fail_core; | 1160 | goto fail_core; |
1091 | 1161 | ||
1092 | err = -ENOMEM; | ||
1093 | dev = kzalloc(sizeof(*dev),GFP_KERNEL); | ||
1094 | if (NULL == dev) | ||
1095 | goto fail_core; | ||
1096 | dev->pci = pci_dev; | ||
1097 | dev->core = core; | ||
1098 | dev->width = 720; | 1162 | dev->width = 720; |
1099 | dev->height = 576; | 1163 | dev->height = 576; |
1100 | cx2341x_fill_defaults(&dev->params); | 1164 | cx2341x_fill_defaults(&dev->params); |
@@ -1106,64 +1170,36 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev, | |||
1106 | dev->height = 576; | 1170 | dev->height = 576; |
1107 | } | 1171 | } |
1108 | 1172 | ||
1109 | err = cx8802_init_common(dev); | ||
1110 | if (0 != err) | ||
1111 | goto fail_free; | ||
1112 | |||
1113 | /* blackbird stuff */ | 1173 | /* blackbird stuff */ |
1114 | printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n", | 1174 | printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n", |
1115 | core->name); | 1175 | core->name); |
1116 | host_setup(dev->core); | 1176 | host_setup(dev->core); |
1117 | 1177 | ||
1118 | list_add_tail(&dev->devlist,&cx8802_devlist); | ||
1119 | blackbird_register_video(dev); | 1178 | blackbird_register_video(dev); |
1120 | 1179 | ||
1121 | /* initial device configuration: needed ? */ | 1180 | /* initial device configuration: needed ? */ |
1122 | 1181 | ||
1123 | return 0; | 1182 | return 0; |
1124 | 1183 | ||
1125 | fail_free: | ||
1126 | kfree(dev); | ||
1127 | fail_core: | 1184 | fail_core: |
1128 | cx88_core_put(core,pci_dev); | ||
1129 | return err; | 1185 | return err; |
1130 | } | 1186 | } |
1131 | 1187 | ||
1132 | static void __devexit blackbird_remove(struct pci_dev *pci_dev) | 1188 | static int cx8802_blackbird_remove(struct cx8802_driver *drv) |
1133 | { | 1189 | { |
1134 | struct cx8802_dev *dev = pci_get_drvdata(pci_dev); | ||
1135 | |||
1136 | /* blackbird */ | 1190 | /* blackbird */ |
1137 | blackbird_unregister_video(dev); | 1191 | blackbird_unregister_video(drv->core->dvbdev); |
1138 | list_del(&dev->devlist); | ||
1139 | 1192 | ||
1140 | /* common */ | 1193 | return 0; |
1141 | cx8802_fini_common(dev); | ||
1142 | cx88_core_put(dev->core,dev->pci); | ||
1143 | kfree(dev); | ||
1144 | } | 1194 | } |
1145 | 1195 | ||
1146 | static struct pci_device_id cx8802_pci_tbl[] = { | 1196 | static struct cx8802_driver cx8802_blackbird_driver = { |
1147 | { | 1197 | .type_id = CX88_MPEG_BLACKBIRD, |
1148 | .vendor = 0x14f1, | 1198 | .hw_access = CX8802_DRVCTL_SHARED, |
1149 | .device = 0x8802, | 1199 | .probe = cx8802_blackbird_probe, |
1150 | .subvendor = PCI_ANY_ID, | 1200 | .remove = cx8802_blackbird_remove, |
1151 | .subdevice = PCI_ANY_ID, | 1201 | .advise_acquire = cx8802_blackbird_advise_acquire, |
1152 | },{ | 1202 | .advise_release = cx8802_blackbird_advise_release, |
1153 | /* --- end of list --- */ | ||
1154 | } | ||
1155 | }; | ||
1156 | MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); | ||
1157 | |||
1158 | static struct pci_driver blackbird_pci_driver = { | ||
1159 | .name = "cx88-blackbird", | ||
1160 | .id_table = cx8802_pci_tbl, | ||
1161 | .probe = blackbird_probe, | ||
1162 | .remove = __devexit_p(blackbird_remove), | ||
1163 | #ifdef CONFIG_PM | ||
1164 | .suspend = cx8802_suspend_common, | ||
1165 | .resume = cx8802_resume_common, | ||
1166 | #endif | ||
1167 | }; | 1203 | }; |
1168 | 1204 | ||
1169 | static int blackbird_init(void) | 1205 | static int blackbird_init(void) |
@@ -1176,17 +1212,22 @@ static int blackbird_init(void) | |||
1176 | printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", | 1212 | printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", |
1177 | SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); | 1213 | SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); |
1178 | #endif | 1214 | #endif |
1179 | return pci_register_driver(&blackbird_pci_driver); | 1215 | cx88_ioctl_hook = mpeg_do_ioctl; |
1216 | cx88_ioctl_translator = mpeg_translate_ioctl; | ||
1217 | return cx8802_register_driver(&cx8802_blackbird_driver); | ||
1180 | } | 1218 | } |
1181 | 1219 | ||
1182 | static void blackbird_fini(void) | 1220 | static void blackbird_fini(void) |
1183 | { | 1221 | { |
1184 | pci_unregister_driver(&blackbird_pci_driver); | 1222 | cx8802_unregister_driver(&cx8802_blackbird_driver); |
1185 | } | 1223 | } |
1186 | 1224 | ||
1187 | module_init(blackbird_init); | 1225 | module_init(blackbird_init); |
1188 | module_exit(blackbird_fini); | 1226 | module_exit(blackbird_fini); |
1189 | 1227 | ||
1228 | EXPORT_SYMBOL(cx88_ioctl_hook); | ||
1229 | EXPORT_SYMBOL(cx88_ioctl_translator); | ||
1230 | |||
1190 | /* ----------------------------------------------------------- */ | 1231 | /* ----------------------------------------------------------- */ |
1191 | /* | 1232 | /* |
1192 | * Local variables: | 1233 | * Local variables: |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index f764a57c56be..c791708b1336 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -281,18 +281,22 @@ struct cx88_board cx88_boards[] = { | |||
281 | .type = CX88_VMUX_TELEVISION, | 281 | .type = CX88_VMUX_TELEVISION, |
282 | .vmux = 0, | 282 | .vmux = 0, |
283 | .gpio0 = 0x0000bde2, | 283 | .gpio0 = 0x0000bde2, |
284 | .extadc = 1, | ||
284 | },{ | 285 | },{ |
285 | .type = CX88_VMUX_COMPOSITE1, | 286 | .type = CX88_VMUX_COMPOSITE1, |
286 | .vmux = 1, | 287 | .vmux = 1, |
287 | .gpio0 = 0x0000bde6, | 288 | .gpio0 = 0x0000bde6, |
289 | .extadc = 1, | ||
288 | },{ | 290 | },{ |
289 | .type = CX88_VMUX_SVIDEO, | 291 | .type = CX88_VMUX_SVIDEO, |
290 | .vmux = 2, | 292 | .vmux = 2, |
291 | .gpio0 = 0x0000bde6, | 293 | .gpio0 = 0x0000bde6, |
294 | .extadc = 1, | ||
292 | }}, | 295 | }}, |
293 | .radio = { | 296 | .radio = { |
294 | .type = CX88_RADIO, | 297 | .type = CX88_RADIO, |
295 | .gpio0 = 0x0000bd62, | 298 | .gpio0 = 0x0000bd62, |
299 | .extadc = 1, | ||
296 | }, | 300 | }, |
297 | .mpeg = CX88_MPEG_BLACKBIRD, | 301 | .mpeg = CX88_MPEG_BLACKBIRD, |
298 | }, | 302 | }, |
@@ -353,6 +357,7 @@ struct cx88_board cx88_boards[] = { | |||
353 | .type = CX88_VMUX_SVIDEO, | 357 | .type = CX88_VMUX_SVIDEO, |
354 | .vmux = 2, | 358 | .vmux = 2, |
355 | .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in? | 359 | .gpio0 = 0x0000fde6, // 0x0000fda6 L,R RCA audio in? |
360 | .extadc = 1, | ||
356 | }}, | 361 | }}, |
357 | .radio = { | 362 | .radio = { |
358 | .type = CX88_RADIO, | 363 | .type = CX88_RADIO, |
@@ -523,6 +528,7 @@ struct cx88_board cx88_boards[] = { | |||
523 | .input = {{ | 528 | .input = {{ |
524 | .type = CX88_VMUX_TELEVISION, | 529 | .type = CX88_VMUX_TELEVISION, |
525 | .vmux = 0, | 530 | .vmux = 0, |
531 | .extadc = 1, | ||
526 | }}, | 532 | }}, |
527 | .mpeg = CX88_MPEG_BLACKBIRD, | 533 | .mpeg = CX88_MPEG_BLACKBIRD, |
528 | }, | 534 | }, |
@@ -646,18 +652,22 @@ struct cx88_board cx88_boards[] = { | |||
646 | .type = CX88_VMUX_TELEVISION, | 652 | .type = CX88_VMUX_TELEVISION, |
647 | .vmux = 0, | 653 | .vmux = 0, |
648 | .gpio0 = 0x00009d80, | 654 | .gpio0 = 0x00009d80, |
655 | .extadc = 1, | ||
649 | },{ | 656 | },{ |
650 | .type = CX88_VMUX_COMPOSITE1, | 657 | .type = CX88_VMUX_COMPOSITE1, |
651 | .vmux = 1, | 658 | .vmux = 1, |
652 | .gpio0 = 0x00009d76, | 659 | .gpio0 = 0x00009d76, |
660 | .extadc = 1, | ||
653 | },{ | 661 | },{ |
654 | .type = CX88_VMUX_SVIDEO, | 662 | .type = CX88_VMUX_SVIDEO, |
655 | .vmux = 2, | 663 | .vmux = 2, |
656 | .gpio0 = 0x00009d76, | 664 | .gpio0 = 0x00009d76, |
665 | .extadc = 1, | ||
657 | }}, | 666 | }}, |
658 | .radio = { | 667 | .radio = { |
659 | .type = CX88_RADIO, | 668 | .type = CX88_RADIO, |
660 | .gpio0 = 0x00009d00, | 669 | .gpio0 = 0x00009d00, |
670 | .extadc = 1, | ||
661 | }, | 671 | }, |
662 | .mpeg = CX88_MPEG_BLACKBIRD, | 672 | .mpeg = CX88_MPEG_BLACKBIRD, |
663 | }, | 673 | }, |
@@ -786,25 +796,29 @@ struct cx88_board cx88_boards[] = { | |||
786 | .tuner_addr = ADDR_UNSET, | 796 | .tuner_addr = ADDR_UNSET, |
787 | .radio_addr = ADDR_UNSET, | 797 | .radio_addr = ADDR_UNSET, |
788 | .tda9887_conf = TDA9887_PRESENT, | 798 | .tda9887_conf = TDA9887_PRESENT, |
789 | .mpeg = CX88_MPEG_BLACKBIRD, | ||
790 | .input = {{ | 799 | .input = {{ |
791 | .type = CX88_VMUX_COMPOSITE1, | 800 | .type = CX88_VMUX_COMPOSITE1, |
792 | .vmux = 0, | 801 | .vmux = 0, |
793 | .gpio0 = 0x0000cd73, | 802 | .gpio0 = 0x0000cd73, |
803 | .extadc = 1, | ||
794 | },{ | 804 | },{ |
795 | .type = CX88_VMUX_SVIDEO, | 805 | .type = CX88_VMUX_SVIDEO, |
796 | .vmux = 1, | 806 | .vmux = 1, |
797 | .gpio0 = 0x0000cd73, | 807 | .gpio0 = 0x0000cd73, |
808 | .extadc = 1, | ||
798 | },{ | 809 | },{ |
799 | .type = CX88_VMUX_TELEVISION, | 810 | .type = CX88_VMUX_TELEVISION, |
800 | .vmux = 3, | 811 | .vmux = 3, |
801 | .gpio0 = 0x0000cdb3, | 812 | .gpio0 = 0x0000cdb3, |
813 | .extadc = 1, | ||
802 | }}, | 814 | }}, |
803 | .radio = { | 815 | .radio = { |
804 | .type = CX88_RADIO, | 816 | .type = CX88_RADIO, |
805 | .vmux = 2, | 817 | .vmux = 2, |
806 | .gpio0 = 0x0000cdf3, | 818 | .gpio0 = 0x0000cdf3, |
819 | .extadc = 1, | ||
807 | }, | 820 | }, |
821 | .mpeg = CX88_MPEG_BLACKBIRD, | ||
808 | }, | 822 | }, |
809 | [CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD] = { | 823 | [CX88_BOARD_KWORLD_VSTREAM_EXPERT_DVD] = { |
810 | /* Alexander Wold <awold@bigfoot.com> */ | 824 | /* Alexander Wold <awold@bigfoot.com> */ |
@@ -1050,7 +1064,6 @@ struct cx88_board cx88_boards[] = { | |||
1050 | .mpeg = CX88_MPEG_DVB, | 1064 | .mpeg = CX88_MPEG_DVB, |
1051 | }, | 1065 | }, |
1052 | [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = { | 1066 | [CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT] = { |
1053 | /* FIXME: Audio not working for s-video / composite inputs. */ | ||
1054 | .name = "KWorld HardwareMpegTV XPert", | 1067 | .name = "KWorld HardwareMpegTV XPert", |
1055 | .tuner_type = TUNER_PHILIPS_TDA8290, | 1068 | .tuner_type = TUNER_PHILIPS_TDA8290, |
1056 | .radio_type = UNSET, | 1069 | .radio_type = UNSET, |
@@ -1065,10 +1078,12 @@ struct cx88_board cx88_boards[] = { | |||
1065 | .type = CX88_VMUX_COMPOSITE1, | 1078 | .type = CX88_VMUX_COMPOSITE1, |
1066 | .vmux = 1, | 1079 | .vmux = 1, |
1067 | .gpio0 = 0x3de6, | 1080 | .gpio0 = 0x3de6, |
1081 | .extadc = 1, | ||
1068 | },{ | 1082 | },{ |
1069 | .type = CX88_VMUX_SVIDEO, | 1083 | .type = CX88_VMUX_SVIDEO, |
1070 | .vmux = 2, | 1084 | .vmux = 2, |
1071 | .gpio0 = 0x3de6, | 1085 | .gpio0 = 0x3de6, |
1086 | .extadc = 1, | ||
1072 | }}, | 1087 | }}, |
1073 | .radio = { | 1088 | .radio = { |
1074 | .type = CX88_RADIO, | 1089 | .type = CX88_RADIO, |
@@ -1252,35 +1267,35 @@ struct cx88_board cx88_boards[] = { | |||
1252 | .gpio0 = 0x070b, | 1267 | .gpio0 = 0x070b, |
1253 | }}, | 1268 | }}, |
1254 | }, | 1269 | }, |
1255 | [CX88_BOARD_TE_DTV_250_OEM_SWANN] = { | 1270 | [CX88_BOARD_TE_DTV_250_OEM_SWANN] = { |
1256 | .name = "Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM", | 1271 | .name = "Shenzhen Tungsten Ages Tech TE-DTV-250 / Swann OEM", |
1257 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | 1272 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
1258 | .radio_type = UNSET, | 1273 | .radio_type = UNSET, |
1259 | .tuner_addr = ADDR_UNSET, | 1274 | .tuner_addr = ADDR_UNSET, |
1260 | .radio_addr = ADDR_UNSET, | 1275 | .radio_addr = ADDR_UNSET, |
1261 | .input = {{ | 1276 | .input = {{ |
1262 | .type = CX88_VMUX_TELEVISION, | 1277 | .type = CX88_VMUX_TELEVISION, |
1263 | .vmux = 0, | 1278 | .vmux = 0, |
1264 | .gpio0 = 0x003fffff, | 1279 | .gpio0 = 0x003fffff, |
1265 | .gpio1 = 0x00e00000, | 1280 | .gpio1 = 0x00e00000, |
1266 | .gpio2 = 0x003fffff, | 1281 | .gpio2 = 0x003fffff, |
1267 | .gpio3 = 0x02000000, | 1282 | .gpio3 = 0x02000000, |
1268 | },{ | 1283 | },{ |
1269 | .type = CX88_VMUX_COMPOSITE1, | 1284 | .type = CX88_VMUX_COMPOSITE1, |
1270 | .vmux = 1, | 1285 | .vmux = 1, |
1271 | .gpio0 = 0x003fffff, | 1286 | .gpio0 = 0x003fffff, |
1272 | .gpio1 = 0x00e00000, | 1287 | .gpio1 = 0x00e00000, |
1273 | .gpio2 = 0x003fffff, | 1288 | .gpio2 = 0x003fffff, |
1274 | .gpio3 = 0x02000000, | 1289 | .gpio3 = 0x02000000, |
1275 | },{ | 1290 | },{ |
1276 | .type = CX88_VMUX_SVIDEO, | 1291 | .type = CX88_VMUX_SVIDEO, |
1277 | .vmux = 2, | 1292 | .vmux = 2, |
1278 | .gpio0 = 0x003fffff, | 1293 | .gpio0 = 0x003fffff, |
1279 | .gpio1 = 0x00e00000, | 1294 | .gpio1 = 0x00e00000, |
1280 | .gpio2 = 0x003fffff, | 1295 | .gpio2 = 0x003fffff, |
1281 | .gpio3 = 0x02000000, | 1296 | .gpio3 = 0x02000000, |
1282 | }}, | 1297 | }}, |
1283 | }, | 1298 | }, |
1284 | [CX88_BOARD_HAUPPAUGE_HVR1300] = { | 1299 | [CX88_BOARD_HAUPPAUGE_HVR1300] = { |
1285 | .name = "Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder", | 1300 | .name = "Hauppauge WinTV-HVR1300 DVB-T/Hybrid MPEG Encoder", |
1286 | .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, | 1301 | .tuner_type = TUNER_PHILIPS_FMD1216ME_MK3, |
@@ -1293,17 +1308,20 @@ struct cx88_board cx88_boards[] = { | |||
1293 | .type = CX88_VMUX_TELEVISION, | 1308 | .type = CX88_VMUX_TELEVISION, |
1294 | .vmux = 0, | 1309 | .vmux = 0, |
1295 | .gpio0 = 0xe780, | 1310 | .gpio0 = 0xe780, |
1311 | .extadc = 1, | ||
1296 | },{ | 1312 | },{ |
1297 | .type = CX88_VMUX_COMPOSITE1, | 1313 | .type = CX88_VMUX_COMPOSITE1, |
1298 | .vmux = 1, | 1314 | .vmux = 1, |
1299 | .gpio0 = 0xe780, | 1315 | .gpio0 = 0xe780, |
1316 | .extadc = 1, | ||
1300 | },{ | 1317 | },{ |
1301 | .type = CX88_VMUX_SVIDEO, | 1318 | .type = CX88_VMUX_SVIDEO, |
1302 | .vmux = 2, | 1319 | .vmux = 2, |
1303 | .gpio0 = 0xe780, | 1320 | .gpio0 = 0xe780, |
1321 | .extadc = 1, | ||
1304 | }}, | 1322 | }}, |
1305 | /* fixme: Add radio support */ | 1323 | /* fixme: Add radio support */ |
1306 | .mpeg = CX88_MPEG_DVB, | 1324 | .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD, |
1307 | }, | 1325 | }, |
1308 | }; | 1326 | }; |
1309 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); | 1327 | const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); |
@@ -1513,6 +1531,10 @@ struct cx88_subid cx88_subids[] = { | |||
1513 | },{ | 1531 | },{ |
1514 | .subvendor = 0x17de, | 1532 | .subvendor = 0x17de, |
1515 | .subdevice = 0x0840, | 1533 | .subdevice = 0x0840, |
1534 | .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT, | ||
1535 | },{ | ||
1536 | .subvendor = 0x1421, | ||
1537 | .subdevice = 0x0305, | ||
1516 | .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT, | 1538 | .card = CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT, |
1517 | },{ | 1539 | },{ |
1518 | .subvendor = 0x18ac, | 1540 | .subvendor = 0x18ac, |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 0ef13e7efa2e..8b203354fccd 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include "cx22702.h" | 42 | #include "cx22702.h" |
43 | #include "or51132.h" | 43 | #include "or51132.h" |
44 | #include "lgdt330x.h" | 44 | #include "lgdt330x.h" |
45 | #include "lg_h06xf.h" | 45 | #include "lgh06xf.h" |
46 | #include "nxt200x.h" | 46 | #include "nxt200x.h" |
47 | #include "cx24123.h" | 47 | #include "cx24123.h" |
48 | #include "isl6421.h" | 48 | #include "isl6421.h" |
@@ -57,7 +57,7 @@ module_param(debug, int, 0644); | |||
57 | MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); | 57 | MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); |
58 | 58 | ||
59 | #define dprintk(level,fmt, arg...) if (debug >= level) \ | 59 | #define dprintk(level,fmt, arg...) if (debug >= level) \ |
60 | printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->core->name , ## arg) | 60 | printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg) |
61 | 61 | ||
62 | /* ------------------------------------------------------------------ */ | 62 | /* ------------------------------------------------------------------ */ |
63 | 63 | ||
@@ -74,8 +74,8 @@ static int dvb_buf_setup(struct videobuf_queue *q, | |||
74 | return 0; | 74 | return 0; |
75 | } | 75 | } |
76 | 76 | ||
77 | static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | 77 | static int dvb_buf_prepare(struct videobuf_queue *q, |
78 | enum v4l2_field field) | 78 | struct videobuf_buffer *vb, enum v4l2_field field) |
79 | { | 79 | { |
80 | struct cx8802_dev *dev = q->priv_data; | 80 | struct cx8802_dev *dev = q->priv_data; |
81 | return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field); | 81 | return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field); |
@@ -87,7 +87,8 @@ static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | |||
87 | cx8802_buf_queue(dev, (struct cx88_buffer*)vb); | 87 | cx8802_buf_queue(dev, (struct cx88_buffer*)vb); |
88 | } | 88 | } |
89 | 89 | ||
90 | static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | 90 | static void dvb_buf_release(struct videobuf_queue *q, |
91 | struct videobuf_buffer *vb) | ||
91 | { | 92 | { |
92 | cx88_free_buffer(q, (struct cx88_buffer*)vb); | 93 | cx88_free_buffer(q, (struct cx88_buffer*)vb); |
93 | } | 94 | } |
@@ -100,6 +101,26 @@ static struct videobuf_queue_ops dvb_qops = { | |||
100 | }; | 101 | }; |
101 | 102 | ||
102 | /* ------------------------------------------------------------------ */ | 103 | /* ------------------------------------------------------------------ */ |
104 | |||
105 | static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) | ||
106 | { | ||
107 | struct cx8802_dev *dev= fe->dvb->priv; | ||
108 | struct cx8802_driver *drv = NULL; | ||
109 | int ret = 0; | ||
110 | |||
111 | drv = cx8802_get_driver(dev, CX88_MPEG_DVB); | ||
112 | if (drv) { | ||
113 | if (acquire) | ||
114 | ret = drv->request_acquire(drv); | ||
115 | else | ||
116 | ret = drv->request_release(drv); | ||
117 | } | ||
118 | |||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | /* ------------------------------------------------------------------ */ | ||
123 | |||
103 | static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) | 124 | static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) |
104 | { | 125 | { |
105 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 }; | 126 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 }; |
@@ -268,35 +289,6 @@ static struct mt352_config dntv_live_dvbt_pro_config = { | |||
268 | }; | 289 | }; |
269 | #endif | 290 | #endif |
270 | 291 | ||
271 | static int dvico_hybrid_tuner_set_params(struct dvb_frontend *fe, | ||
272 | struct dvb_frontend_parameters *params) | ||
273 | { | ||
274 | u8 pllbuf[4]; | ||
275 | struct cx8802_dev *dev= fe->dvb->priv; | ||
276 | struct i2c_msg msg = | ||
277 | { .addr = dev->core->pll_addr, .flags = 0, | ||
278 | .buf = pllbuf, .len = 4 }; | ||
279 | int err; | ||
280 | |||
281 | dvb_pll_configure(dev->core->pll_desc, pllbuf, | ||
282 | params->frequency, | ||
283 | params->u.ofdm.bandwidth); | ||
284 | |||
285 | if (fe->ops.i2c_gate_ctrl) | ||
286 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
287 | if ((err = i2c_transfer(&dev->core->i2c_adap, &msg, 1)) != 1) { | ||
288 | printk(KERN_WARNING "cx88-dvb: %s error " | ||
289 | "(addr %02x <- %02x, err = %i)\n", | ||
290 | __FUNCTION__, pllbuf[0], pllbuf[1], err); | ||
291 | if (err < 0) | ||
292 | return err; | ||
293 | else | ||
294 | return -EREMOTEIO; | ||
295 | } | ||
296 | |||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static struct zl10353_config dvico_fusionhdtv_hybrid = { | 292 | static struct zl10353_config dvico_fusionhdtv_hybrid = { |
301 | .demod_address = 0x0f, | 293 | .demod_address = 0x0f, |
302 | .no_tuner = 1, | 294 | .no_tuner = 1, |
@@ -311,28 +303,12 @@ static struct cx22702_config connexant_refboard_config = { | |||
311 | .output_mode = CX22702_SERIAL_OUTPUT, | 303 | .output_mode = CX22702_SERIAL_OUTPUT, |
312 | }; | 304 | }; |
313 | 305 | ||
314 | static struct cx22702_config hauppauge_novat_config = { | 306 | static struct cx22702_config hauppauge_hvr_config = { |
315 | .demod_address = 0x43, | ||
316 | .output_mode = CX22702_SERIAL_OUTPUT, | ||
317 | }; | ||
318 | |||
319 | static struct cx22702_config hauppauge_hvr1100_config = { | ||
320 | .demod_address = 0x63, | 307 | .demod_address = 0x63, |
321 | .output_mode = CX22702_SERIAL_OUTPUT, | 308 | .output_mode = CX22702_SERIAL_OUTPUT, |
322 | }; | 309 | }; |
323 | 310 | ||
324 | static struct cx22702_config hauppauge_hvr1300_config = { | 311 | static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured) |
325 | .demod_address = 0x63, | ||
326 | .output_mode = CX22702_SERIAL_OUTPUT, | ||
327 | }; | ||
328 | |||
329 | static struct cx22702_config hauppauge_hvr3000_config = { | ||
330 | .demod_address = 0x63, | ||
331 | .output_mode = CX22702_SERIAL_OUTPUT, | ||
332 | }; | ||
333 | |||
334 | static int or51132_set_ts_param(struct dvb_frontend* fe, | ||
335 | int is_punctured) | ||
336 | { | 312 | { |
337 | struct cx8802_dev *dev= fe->dvb->priv; | 313 | struct cx8802_dev *dev= fe->dvb->priv; |
338 | dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; | 314 | dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; |
@@ -344,50 +320,6 @@ static struct or51132_config pchdtv_hd3000 = { | |||
344 | .set_ts_params = or51132_set_ts_param, | 320 | .set_ts_params = or51132_set_ts_param, |
345 | }; | 321 | }; |
346 | 322 | ||
347 | static int lgdt3302_tuner_set_params(struct dvb_frontend* fe, | ||
348 | struct dvb_frontend_parameters* params) | ||
349 | { | ||
350 | /* FIXME make this routine use the tuner-simple code. | ||
351 | * It could probably be shared with a number of ATSC | ||
352 | * frontends. Many share the same tuner with analog TV. */ | ||
353 | |||
354 | struct cx8802_dev *dev= fe->dvb->priv; | ||
355 | struct cx88_core *core = dev->core; | ||
356 | u8 buf[4]; | ||
357 | struct i2c_msg msg = | ||
358 | { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 }; | ||
359 | int err; | ||
360 | |||
361 | dvb_pll_configure(core->pll_desc, buf, params->frequency, 0); | ||
362 | dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n", | ||
363 | __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]); | ||
364 | |||
365 | if (fe->ops.i2c_gate_ctrl) | ||
366 | fe->ops.i2c_gate_ctrl(fe, 1); | ||
367 | if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) { | ||
368 | printk(KERN_WARNING "cx88-dvb: %s error " | ||
369 | "(addr %02x <- %02x, err = %i)\n", | ||
370 | __FUNCTION__, buf[0], buf[1], err); | ||
371 | if (err < 0) | ||
372 | return err; | ||
373 | else | ||
374 | return -EREMOTEIO; | ||
375 | } | ||
376 | return 0; | ||
377 | } | ||
378 | |||
379 | static int lgdt3303_tuner_set_params(struct dvb_frontend* fe, | ||
380 | struct dvb_frontend_parameters* params) | ||
381 | { | ||
382 | struct cx8802_dev *dev= fe->dvb->priv; | ||
383 | struct cx88_core *core = dev->core; | ||
384 | |||
385 | /* Put the analog decoder in standby to keep it quiet */ | ||
386 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | ||
387 | |||
388 | return lg_h06xf_pll_set(fe, &core->i2c_adap, params); | ||
389 | } | ||
390 | |||
391 | static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) | 323 | static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) |
392 | { | 324 | { |
393 | struct cx8802_dev *dev= fe->dvb->priv; | 325 | struct cx8802_dev *dev= fe->dvb->priv; |
@@ -432,8 +364,7 @@ static struct lgdt330x_config pchdtv_hd5500 = { | |||
432 | .set_ts_params = lgdt330x_set_ts_param, | 364 | .set_ts_params = lgdt330x_set_ts_param, |
433 | }; | 365 | }; |
434 | 366 | ||
435 | static int nxt200x_set_ts_param(struct dvb_frontend* fe, | 367 | static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured) |
436 | int is_punctured) | ||
437 | { | 368 | { |
438 | struct cx8802_dev *dev= fe->dvb->priv; | 369 | struct cx8802_dev *dev= fe->dvb->priv; |
439 | dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; | 370 | dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; |
@@ -469,11 +400,10 @@ static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, | |||
469 | struct cx8802_dev *dev= fe->dvb->priv; | 400 | struct cx8802_dev *dev= fe->dvb->priv; |
470 | struct cx88_core *core = dev->core; | 401 | struct cx88_core *core = dev->core; |
471 | 402 | ||
472 | if (voltage == SEC_VOLTAGE_OFF) { | 403 | if (voltage == SEC_VOLTAGE_OFF) |
473 | cx_write(MO_GP0_IO, 0x000006fb); | 404 | cx_write(MO_GP0_IO, 0x000006fb); |
474 | } else { | 405 | else |
475 | cx_write(MO_GP0_IO, 0x000006f9); | 406 | cx_write(MO_GP0_IO, 0x000006f9); |
476 | } | ||
477 | 407 | ||
478 | if (core->prev_set_voltage) | 408 | if (core->prev_set_voltage) |
479 | return core->prev_set_voltage(fe, voltage); | 409 | return core->prev_set_voltage(fe, voltage); |
@@ -522,7 +452,7 @@ static int dvb_register(struct cx8802_dev *dev) | |||
522 | switch (dev->core->board) { | 452 | switch (dev->core->board) { |
523 | case CX88_BOARD_HAUPPAUGE_DVB_T1: | 453 | case CX88_BOARD_HAUPPAUGE_DVB_T1: |
524 | dev->dvb.frontend = dvb_attach(cx22702_attach, | 454 | dev->dvb.frontend = dvb_attach(cx22702_attach, |
525 | &hauppauge_novat_config, | 455 | &connexant_refboard_config, |
526 | &dev->core->i2c_adap); | 456 | &dev->core->i2c_adap); |
527 | if (dev->dvb.frontend != NULL) { | 457 | if (dev->dvb.frontend != NULL) { |
528 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 458 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
@@ -547,32 +477,11 @@ static int dvb_register(struct cx8802_dev *dev) | |||
547 | case CX88_BOARD_HAUPPAUGE_HVR1100: | 477 | case CX88_BOARD_HAUPPAUGE_HVR1100: |
548 | case CX88_BOARD_HAUPPAUGE_HVR1100LP: | 478 | case CX88_BOARD_HAUPPAUGE_HVR1100LP: |
549 | dev->dvb.frontend = dvb_attach(cx22702_attach, | 479 | dev->dvb.frontend = dvb_attach(cx22702_attach, |
550 | &hauppauge_hvr1100_config, | 480 | &hauppauge_hvr_config, |
551 | &dev->core->i2c_adap); | ||
552 | if (dev->dvb.frontend != NULL) { | ||
553 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | ||
554 | &dev->core->i2c_adap, | ||
555 | &dvb_pll_fmd1216me); | ||
556 | } | ||
557 | break; | ||
558 | case CX88_BOARD_HAUPPAUGE_HVR1300: | ||
559 | dev->dvb.frontend = dvb_attach(cx22702_attach, | ||
560 | &hauppauge_hvr1300_config, | ||
561 | &dev->core->i2c_adap); | ||
562 | if (dev->dvb.frontend != NULL) { | ||
563 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | ||
564 | &dev->core->i2c_adap, | ||
565 | &dvb_pll_fmd1216me); | ||
566 | } | ||
567 | break; | ||
568 | case CX88_BOARD_HAUPPAUGE_HVR3000: | ||
569 | dev->dvb.frontend = dvb_attach(cx22702_attach, | ||
570 | &hauppauge_hvr3000_config, | ||
571 | &dev->core->i2c_adap); | 481 | &dev->core->i2c_adap); |
572 | if (dev->dvb.frontend != NULL) { | 482 | if (dev->dvb.frontend != NULL) { |
573 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 483 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
574 | &dev->core->i2c_adap, | 484 | &dev->core->i2c_adap, &dvb_pll_fmd1216me); |
575 | &dvb_pll_fmd1216me); | ||
576 | } | 485 | } |
577 | break; | 486 | break; |
578 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: | 487 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: |
@@ -647,18 +556,17 @@ static int dvb_register(struct cx8802_dev *dev) | |||
647 | #endif | 556 | #endif |
648 | break; | 557 | break; |
649 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: | 558 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: |
650 | dev->core->pll_addr = 0x61; | ||
651 | dev->core->pll_desc = &dvb_pll_thomson_fe6600; | ||
652 | dev->dvb.frontend = dvb_attach(zl10353_attach, | 559 | dev->dvb.frontend = dvb_attach(zl10353_attach, |
653 | &dvico_fusionhdtv_hybrid, | 560 | &dvico_fusionhdtv_hybrid, |
654 | &dev->core->i2c_adap); | 561 | &dev->core->i2c_adap); |
655 | if (dev->dvb.frontend != NULL) { | 562 | if (dev->dvb.frontend != NULL) { |
656 | dev->dvb.frontend->ops.tuner_ops.set_params = dvico_hybrid_tuner_set_params; | 563 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
564 | &dev->core->i2c_adap, | ||
565 | &dvb_pll_thomson_fe6600); | ||
657 | } | 566 | } |
658 | break; | 567 | break; |
659 | case CX88_BOARD_PCHDTV_HD3000: | 568 | case CX88_BOARD_PCHDTV_HD3000: |
660 | dev->dvb.frontend = dvb_attach(or51132_attach, | 569 | dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, |
661 | &pchdtv_hd3000, | ||
662 | &dev->core->i2c_adap); | 570 | &dev->core->i2c_adap); |
663 | if (dev->dvb.frontend != NULL) { | 571 | if (dev->dvb.frontend != NULL) { |
664 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | 572 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
@@ -679,13 +587,13 @@ static int dvb_register(struct cx8802_dev *dev) | |||
679 | 587 | ||
680 | /* Select RF connector callback */ | 588 | /* Select RF connector callback */ |
681 | fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; | 589 | fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; |
682 | dev->core->pll_addr = 0x61; | ||
683 | dev->core->pll_desc = &dvb_pll_microtune_4042; | ||
684 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, | 590 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, |
685 | &fusionhdtv_3_gold, | 591 | &fusionhdtv_3_gold, |
686 | &dev->core->i2c_adap); | 592 | &dev->core->i2c_adap); |
687 | if (dev->dvb.frontend != NULL) { | 593 | if (dev->dvb.frontend != NULL) { |
688 | dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3302_tuner_set_params; | 594 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
595 | &dev->core->i2c_adap, | ||
596 | &dvb_pll_microtune_4042); | ||
689 | } | 597 | } |
690 | } | 598 | } |
691 | break; | 599 | break; |
@@ -699,13 +607,13 @@ static int dvb_register(struct cx8802_dev *dev) | |||
699 | mdelay(100); | 607 | mdelay(100); |
700 | cx_set(MO_GP0_IO, 9); | 608 | cx_set(MO_GP0_IO, 9); |
701 | mdelay(200); | 609 | mdelay(200); |
702 | dev->core->pll_addr = 0x61; | ||
703 | dev->core->pll_desc = &dvb_pll_thomson_dtt761x; | ||
704 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, | 610 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, |
705 | &fusionhdtv_3_gold, | 611 | &fusionhdtv_3_gold, |
706 | &dev->core->i2c_adap); | 612 | &dev->core->i2c_adap); |
707 | if (dev->dvb.frontend != NULL) { | 613 | if (dev->dvb.frontend != NULL) { |
708 | dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3302_tuner_set_params; | 614 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
615 | &dev->core->i2c_adap, | ||
616 | &dvb_pll_thomson_dtt761x); | ||
709 | } | 617 | } |
710 | } | 618 | } |
711 | break; | 619 | break; |
@@ -723,7 +631,8 @@ static int dvb_register(struct cx8802_dev *dev) | |||
723 | &fusionhdtv_5_gold, | 631 | &fusionhdtv_5_gold, |
724 | &dev->core->i2c_adap); | 632 | &dev->core->i2c_adap); |
725 | if (dev->dvb.frontend != NULL) { | 633 | if (dev->dvb.frontend != NULL) { |
726 | dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; | 634 | dvb_attach(lgh06xf_attach, dev->dvb.frontend, |
635 | &dev->core->i2c_adap); | ||
727 | } | 636 | } |
728 | } | 637 | } |
729 | break; | 638 | break; |
@@ -741,7 +650,8 @@ static int dvb_register(struct cx8802_dev *dev) | |||
741 | &pchdtv_hd5500, | 650 | &pchdtv_hd5500, |
742 | &dev->core->i2c_adap); | 651 | &dev->core->i2c_adap); |
743 | if (dev->dvb.frontend != NULL) { | 652 | if (dev->dvb.frontend != NULL) { |
744 | dev->dvb.frontend->ops.tuner_ops.set_params = lgdt3303_tuner_set_params; | 653 | dvb_attach(lgh06xf_attach, dev->dvb.frontend, |
654 | &dev->core->i2c_adap); | ||
745 | } | 655 | } |
746 | } | 656 | } |
747 | break; | 657 | break; |
@@ -782,6 +692,24 @@ static int dvb_register(struct cx8802_dev *dev) | |||
782 | dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; | 692 | dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; |
783 | } | 693 | } |
784 | break; | 694 | break; |
695 | case CX88_BOARD_HAUPPAUGE_HVR1300: | ||
696 | dev->dvb.frontend = dvb_attach(cx22702_attach, | ||
697 | &hauppauge_hvr_config, | ||
698 | &dev->core->i2c_adap); | ||
699 | if (dev->dvb.frontend != NULL) { | ||
700 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | ||
701 | &dev->core->i2c_adap, &dvb_pll_fmd1216me); | ||
702 | } | ||
703 | break; | ||
704 | case CX88_BOARD_HAUPPAUGE_HVR3000: | ||
705 | dev->dvb.frontend = dvb_attach(cx22702_attach, | ||
706 | &hauppauge_hvr_config, | ||
707 | &dev->core->i2c_adap); | ||
708 | if (dev->dvb.frontend != NULL) { | ||
709 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, | ||
710 | &dev->core->i2c_adap, &dvb_pll_fmd1216me); | ||
711 | } | ||
712 | break; | ||
785 | default: | 713 | default: |
786 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", | 714 | printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", |
787 | dev->core->name); | 715 | dev->core->name); |
@@ -796,6 +724,8 @@ static int dvb_register(struct cx8802_dev *dev) | |||
796 | dev->dvb.frontend->ops.info.frequency_min = dev->core->pll_desc->min; | 724 | dev->dvb.frontend->ops.info.frequency_min = dev->core->pll_desc->min; |
797 | dev->dvb.frontend->ops.info.frequency_max = dev->core->pll_desc->max; | 725 | dev->dvb.frontend->ops.info.frequency_max = dev->core->pll_desc->max; |
798 | } | 726 | } |
727 | /* Ensure all frontends negotiate bus access */ | ||
728 | dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; | ||
799 | 729 | ||
800 | /* Put the analog decoder in standby to keep it quiet */ | 730 | /* Put the analog decoder in standby to keep it quiet */ |
801 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | 731 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); |
@@ -806,37 +736,67 @@ static int dvb_register(struct cx8802_dev *dev) | |||
806 | 736 | ||
807 | /* ----------------------------------------------------------- */ | 737 | /* ----------------------------------------------------------- */ |
808 | 738 | ||
809 | static int __devinit dvb_probe(struct pci_dev *pci_dev, | 739 | /* CX8802 MPEG -> mini driver - We have been given the hardware */ |
810 | const struct pci_device_id *pci_id) | 740 | static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) |
811 | { | 741 | { |
812 | struct cx8802_dev *dev; | 742 | struct cx88_core *core = drv->core; |
813 | struct cx88_core *core; | 743 | int err = 0; |
744 | dprintk( 1, "%s\n", __FUNCTION__); | ||
745 | |||
746 | switch (core->board) { | ||
747 | case CX88_BOARD_HAUPPAUGE_HVR1300: | ||
748 | /* We arrive here with either the cx23416 or the cx22702 | ||
749 | * on the bus. Take the bus from the cx23416 and enable the | ||
750 | * cx22702 demod | ||
751 | */ | ||
752 | cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset and enable */ | ||
753 | cx_clear(MO_GP0_IO, 0x00000004); | ||
754 | udelay(1000); | ||
755 | break; | ||
756 | default: | ||
757 | err = -ENODEV; | ||
758 | } | ||
759 | return err; | ||
760 | } | ||
761 | |||
762 | /* CX8802 MPEG -> mini driver - We no longer have the hardware */ | ||
763 | static int cx8802_dvb_advise_release(struct cx8802_driver *drv) | ||
764 | { | ||
765 | struct cx88_core *core = drv->core; | ||
766 | int err = 0; | ||
767 | dprintk( 1, "%s\n", __FUNCTION__); | ||
768 | |||
769 | switch (core->board) { | ||
770 | case CX88_BOARD_HAUPPAUGE_HVR1300: | ||
771 | /* Do Nothing, leave the cx22702 on the bus. */ | ||
772 | break; | ||
773 | default: | ||
774 | err = -ENODEV; | ||
775 | } | ||
776 | return err; | ||
777 | } | ||
778 | |||
779 | static int cx8802_dvb_probe(struct cx8802_driver *drv) | ||
780 | { | ||
781 | struct cx88_core *core = drv->core; | ||
782 | struct cx8802_dev *dev = drv->core->dvbdev; | ||
814 | int err; | 783 | int err; |
815 | 784 | ||
816 | /* general setup */ | 785 | dprintk( 1, "%s\n", __FUNCTION__); |
817 | core = cx88_core_get(pci_dev); | 786 | dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", |
818 | if (NULL == core) | 787 | core->board, |
819 | return -EINVAL; | 788 | core->name, |
789 | core->pci_bus, | ||
790 | core->pci_slot); | ||
820 | 791 | ||
821 | err = -ENODEV; | 792 | err = -ENODEV; |
822 | if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB)) | 793 | if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB)) |
823 | goto fail_core; | 794 | goto fail_core; |
824 | 795 | ||
825 | err = -ENOMEM; | ||
826 | dev = kzalloc(sizeof(*dev),GFP_KERNEL); | ||
827 | if (NULL == dev) | ||
828 | goto fail_core; | ||
829 | dev->pci = pci_dev; | ||
830 | dev->core = core; | ||
831 | |||
832 | err = cx8802_init_common(dev); | ||
833 | if (0 != err) | ||
834 | goto fail_free; | ||
835 | |||
836 | #ifdef HAVE_VP3054_I2C | 796 | #ifdef HAVE_VP3054_I2C |
837 | err = vp3054_i2c_probe(dev); | 797 | err = vp3054_i2c_probe(dev); |
838 | if (0 != err) | 798 | if (0 != err) |
839 | goto fail_free; | 799 | goto fail_core; |
840 | #endif | 800 | #endif |
841 | 801 | ||
842 | /* dvb stuff */ | 802 | /* dvb stuff */ |
@@ -848,28 +808,16 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev, | |||
848 | sizeof(struct cx88_buffer), | 808 | sizeof(struct cx88_buffer), |
849 | dev); | 809 | dev); |
850 | err = dvb_register(dev); | 810 | err = dvb_register(dev); |
851 | if (0 != err) | 811 | if (err != 0) |
852 | goto fail_fini; | 812 | printk("%s dvb_register failed err = %d\n", __FUNCTION__, err); |
853 | 813 | ||
854 | /* Maintain a reference to cx88-video can query the 8802 device. */ | ||
855 | core->dvbdev = dev; | ||
856 | return 0; | ||
857 | |||
858 | fail_fini: | ||
859 | cx8802_fini_common(dev); | ||
860 | fail_free: | ||
861 | kfree(dev); | ||
862 | fail_core: | 814 | fail_core: |
863 | cx88_core_put(core,pci_dev); | ||
864 | return err; | 815 | return err; |
865 | } | 816 | } |
866 | 817 | ||
867 | static void __devexit dvb_remove(struct pci_dev *pci_dev) | 818 | static int cx8802_dvb_remove(struct cx8802_driver *drv) |
868 | { | 819 | { |
869 | struct cx8802_dev *dev = pci_get_drvdata(pci_dev); | 820 | struct cx8802_dev *dev = drv->core->dvbdev; |
870 | |||
871 | /* Destroy any 8802 reference. */ | ||
872 | dev->core->dvbdev = NULL; | ||
873 | 821 | ||
874 | /* dvb */ | 822 | /* dvb */ |
875 | videobuf_dvb_unregister(&dev->dvb); | 823 | videobuf_dvb_unregister(&dev->dvb); |
@@ -878,33 +826,16 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev) | |||
878 | vp3054_i2c_remove(dev); | 826 | vp3054_i2c_remove(dev); |
879 | #endif | 827 | #endif |
880 | 828 | ||
881 | /* common */ | 829 | return 0; |
882 | cx8802_fini_common(dev); | ||
883 | cx88_core_put(dev->core,dev->pci); | ||
884 | kfree(dev); | ||
885 | } | 830 | } |
886 | 831 | ||
887 | static struct pci_device_id cx8802_pci_tbl[] = { | 832 | static struct cx8802_driver cx8802_dvb_driver = { |
888 | { | 833 | .type_id = CX88_MPEG_DVB, |
889 | .vendor = 0x14f1, | 834 | .hw_access = CX8802_DRVCTL_SHARED, |
890 | .device = 0x8802, | 835 | .probe = cx8802_dvb_probe, |
891 | .subvendor = PCI_ANY_ID, | 836 | .remove = cx8802_dvb_remove, |
892 | .subdevice = PCI_ANY_ID, | 837 | .advise_acquire = cx8802_dvb_advise_acquire, |
893 | },{ | 838 | .advise_release = cx8802_dvb_advise_release, |
894 | /* --- end of list --- */ | ||
895 | } | ||
896 | }; | ||
897 | MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); | ||
898 | |||
899 | static struct pci_driver dvb_pci_driver = { | ||
900 | .name = "cx88-dvb", | ||
901 | .id_table = cx8802_pci_tbl, | ||
902 | .probe = dvb_probe, | ||
903 | .remove = __devexit_p(dvb_remove), | ||
904 | #ifdef CONFIG_PM | ||
905 | .suspend = cx8802_suspend_common, | ||
906 | .resume = cx8802_resume_common, | ||
907 | #endif | ||
908 | }; | 839 | }; |
909 | 840 | ||
910 | static int dvb_init(void) | 841 | static int dvb_init(void) |
@@ -917,12 +848,12 @@ static int dvb_init(void) | |||
917 | printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", | 848 | printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", |
918 | SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); | 849 | SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); |
919 | #endif | 850 | #endif |
920 | return pci_register_driver(&dvb_pci_driver); | 851 | return cx8802_register_driver(&cx8802_dvb_driver); |
921 | } | 852 | } |
922 | 853 | ||
923 | static void dvb_fini(void) | 854 | static void dvb_fini(void) |
924 | { | 855 | { |
925 | pci_unregister_driver(&dvb_pci_driver); | 856 | cx8802_unregister_driver(&cx8802_dvb_driver); |
926 | } | 857 | } |
927 | 858 | ||
928 | module_init(dvb_init); | 859 | module_init(dvb_init); |
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c index e60a0a52e4b2..8136673fe9e8 100644 --- a/drivers/media/video/cx88/cx88-input.c +++ b/drivers/media/video/cx88/cx88-input.c | |||
@@ -155,6 +155,35 @@ static void cx88_ir_work(struct work_struct *work) | |||
155 | mod_timer(&ir->timer, timeout); | 155 | mod_timer(&ir->timer, timeout); |
156 | } | 156 | } |
157 | 157 | ||
158 | static void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir) | ||
159 | { | ||
160 | if (ir->polling) { | ||
161 | INIT_WORK(&ir->work, cx88_ir_work); | ||
162 | init_timer(&ir->timer); | ||
163 | ir->timer.function = ir_timer; | ||
164 | ir->timer.data = (unsigned long)ir; | ||
165 | schedule_work(&ir->work); | ||
166 | } | ||
167 | if (ir->sampling) { | ||
168 | core->pci_irqmask |= (1 << 18); /* IR_SMP_INT */ | ||
169 | cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */ | ||
170 | cx_write(MO_DDSCFG_IO, 0x5); /* enable */ | ||
171 | } | ||
172 | } | ||
173 | |||
174 | static void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir) | ||
175 | { | ||
176 | if (ir->sampling) { | ||
177 | cx_write(MO_DDSCFG_IO, 0x0); | ||
178 | core->pci_irqmask &= ~(1 << 18); | ||
179 | } | ||
180 | |||
181 | if (ir->polling) { | ||
182 | del_timer_sync(&ir->timer); | ||
183 | flush_scheduled_work(); | ||
184 | } | ||
185 | } | ||
186 | |||
158 | /* ---------------------------------------------------------------------- */ | 187 | /* ---------------------------------------------------------------------- */ |
159 | 188 | ||
160 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | 189 | int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) |
@@ -163,14 +192,12 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
163 | struct input_dev *input_dev; | 192 | struct input_dev *input_dev; |
164 | IR_KEYTAB_TYPE *ir_codes = NULL; | 193 | IR_KEYTAB_TYPE *ir_codes = NULL; |
165 | int ir_type = IR_TYPE_OTHER; | 194 | int ir_type = IR_TYPE_OTHER; |
195 | int err = -ENOMEM; | ||
166 | 196 | ||
167 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | 197 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); |
168 | input_dev = input_allocate_device(); | 198 | input_dev = input_allocate_device(); |
169 | if (!ir || !input_dev) { | 199 | if (!ir || !input_dev) |
170 | kfree(ir); | 200 | goto err_out_free; |
171 | input_free_device(input_dev); | ||
172 | return -ENOMEM; | ||
173 | } | ||
174 | 201 | ||
175 | ir->input = input_dev; | 202 | ir->input = input_dev; |
176 | 203 | ||
@@ -280,9 +307,8 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
280 | } | 307 | } |
281 | 308 | ||
282 | if (NULL == ir_codes) { | 309 | if (NULL == ir_codes) { |
283 | kfree(ir); | 310 | err = -ENODEV; |
284 | input_free_device(input_dev); | 311 | goto err_out_free; |
285 | return -ENODEV; | ||
286 | } | 312 | } |
287 | 313 | ||
288 | /* init input device */ | 314 | /* init input device */ |
@@ -307,23 +333,22 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci) | |||
307 | ir->core = core; | 333 | ir->core = core; |
308 | core->ir = ir; | 334 | core->ir = ir; |
309 | 335 | ||
310 | if (ir->polling) { | 336 | cx88_ir_start(core, ir); |
311 | INIT_WORK(&ir->work, cx88_ir_work); | ||
312 | init_timer(&ir->timer); | ||
313 | ir->timer.function = ir_timer; | ||
314 | ir->timer.data = (unsigned long)ir; | ||
315 | schedule_work(&ir->work); | ||
316 | } | ||
317 | if (ir->sampling) { | ||
318 | core->pci_irqmask |= (1 << 18); /* IR_SMP_INT */ | ||
319 | cx_write(MO_DDS_IO, 0xa80a80); /* 4 kHz sample rate */ | ||
320 | cx_write(MO_DDSCFG_IO, 0x5); /* enable */ | ||
321 | } | ||
322 | 337 | ||
323 | /* all done */ | 338 | /* all done */ |
324 | input_register_device(ir->input); | 339 | err = input_register_device(ir->input); |
340 | if (err) | ||
341 | goto err_out_stop; | ||
325 | 342 | ||
326 | return 0; | 343 | return 0; |
344 | |||
345 | err_out_stop: | ||
346 | cx88_ir_stop(core, ir); | ||
347 | core->ir = NULL; | ||
348 | err_out_free: | ||
349 | input_free_device(input_dev); | ||
350 | kfree(ir); | ||
351 | return err; | ||
327 | } | 352 | } |
328 | 353 | ||
329 | int cx88_ir_fini(struct cx88_core *core) | 354 | int cx88_ir_fini(struct cx88_core *core) |
@@ -334,15 +359,7 @@ int cx88_ir_fini(struct cx88_core *core) | |||
334 | if (NULL == ir) | 359 | if (NULL == ir) |
335 | return 0; | 360 | return 0; |
336 | 361 | ||
337 | if (ir->sampling) { | 362 | cx88_ir_stop(core, ir); |
338 | cx_write(MO_DDSCFG_IO, 0x0); | ||
339 | core->pci_irqmask &= ~(1 << 18); | ||
340 | } | ||
341 | if (ir->polling) { | ||
342 | del_timer(&ir->timer); | ||
343 | flush_scheduled_work(); | ||
344 | } | ||
345 | |||
346 | input_unregister_device(ir->input); | 363 | input_unregister_device(ir->input); |
347 | kfree(ir); | 364 | kfree(ir); |
348 | 365 | ||
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 6b23a4e6f66d..1fe1a833c7c7 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -44,8 +44,12 @@ module_param(debug,int,0644); | |||
44 | MODULE_PARM_DESC(debug,"enable debug messages [mpeg]"); | 44 | MODULE_PARM_DESC(debug,"enable debug messages [mpeg]"); |
45 | 45 | ||
46 | #define dprintk(level,fmt, arg...) if (debug >= level) \ | 46 | #define dprintk(level,fmt, arg...) if (debug >= level) \ |
47 | printk(KERN_DEBUG "%s/2: " fmt, dev->core->name , ## arg) | 47 | printk(KERN_DEBUG "%s/2-mpeg: " fmt, dev->core->name, ## arg) |
48 | 48 | ||
49 | #define mpeg_dbg(level,fmt, arg...) if (debug >= level) \ | ||
50 | printk(KERN_DEBUG "%s/2-mpeg: " fmt, core->name, ## arg) | ||
51 | |||
52 | static LIST_HEAD(cx8802_devlist); | ||
49 | /* ------------------------------------------------------------------ */ | 53 | /* ------------------------------------------------------------------ */ |
50 | 54 | ||
51 | static int cx8802_start_dma(struct cx8802_dev *dev, | 55 | static int cx8802_start_dma(struct cx8802_dev *dev, |
@@ -65,17 +69,13 @@ static int cx8802_start_dma(struct cx8802_dev *dev, | |||
65 | 69 | ||
66 | /* FIXME: this needs a review. | 70 | /* FIXME: this needs a review. |
67 | * also: move to cx88-blackbird + cx88-dvb source files? */ | 71 | * also: move to cx88-blackbird + cx88-dvb source files? */ |
68 | if (cx88_boards[core->board].mpeg == (CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD) ) { | ||
69 | /* Report a warning until the mini driver patch is applied, | ||
70 | * else the following conditions will set the dma registers incorrectly. | ||
71 | * This will be removed in the next major patch and changes to the conditions | ||
72 | * will be made. | ||
73 | */ | ||
74 | printk(KERN_INFO "%s() board->(CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD) is invalid\n", __FUNCTION__); | ||
75 | return -EINVAL; | ||
76 | } | ||
77 | 72 | ||
78 | if (cx88_boards[core->board].mpeg & CX88_MPEG_DVB) { | 73 | dprintk( 1, "core->active_type_id = 0x%08x\n", core->active_type_id); |
74 | |||
75 | if ( (core->active_type_id == CX88_MPEG_DVB) && | ||
76 | (cx88_boards[core->board].mpeg & CX88_MPEG_DVB) ) { | ||
77 | |||
78 | dprintk( 1, "cx8802_start_dma doing .dvb\n"); | ||
79 | /* negedge driven & software reset */ | 79 | /* negedge driven & software reset */ |
80 | cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl); | 80 | cx_write(TS_GEN_CNTRL, 0x0040 | dev->ts_gen_cntrl); |
81 | udelay(100); | 81 | udelay(100); |
@@ -93,15 +93,17 @@ static int cx8802_start_dma(struct cx8802_dev *dev, | |||
93 | cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */ | 93 | cx_write(MO_PINMUX_IO, 0x88); /* Enable MPEG parallel IO and video signal pins */ |
94 | udelay(100); | 94 | udelay(100); |
95 | break; | 95 | break; |
96 | case CX88_BOARD_HAUPPAUGE_HVR1300: | ||
97 | break; | ||
96 | default: | 98 | default: |
97 | cx_write(TS_SOP_STAT, 0x00); | 99 | cx_write(TS_SOP_STAT, 0x00); |
98 | break; | 100 | break; |
99 | } | 101 | } |
100 | cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl); | 102 | cx_write(TS_GEN_CNTRL, dev->ts_gen_cntrl); |
101 | udelay(100); | 103 | udelay(100); |
102 | } | 104 | } else if ( (core->active_type_id == CX88_MPEG_BLACKBIRD) && |
103 | 105 | (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) ) { | |
104 | if (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) { | 106 | dprintk( 1, "cx8802_start_dma doing .blackbird\n"); |
105 | cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */ | 107 | cx_write(MO_PINMUX_IO, 0x88); /* enable MPEG parallel IO */ |
106 | 108 | ||
107 | cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */ | 109 | cx_write(TS_GEN_CNTRL, 0x46); /* punctured clock TS & posedge driven & software reset */ |
@@ -112,6 +114,10 @@ static int cx8802_start_dma(struct cx8802_dev *dev, | |||
112 | 114 | ||
113 | cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */ | 115 | cx_write(TS_GEN_CNTRL, 0x06); /* punctured clock TS & posedge driven */ |
114 | udelay(100); | 116 | udelay(100); |
117 | } else { | ||
118 | printk( "%s() Failed. Unsupported value in .mpeg (0x%08x)\n", __FUNCTION__, | ||
119 | cx88_boards[core->board].mpeg ); | ||
120 | return -EINVAL; | ||
115 | } | 121 | } |
116 | 122 | ||
117 | /* reset counter */ | 123 | /* reset counter */ |
@@ -542,8 +548,315 @@ int cx8802_resume_common(struct pci_dev *pci_dev) | |||
542 | return 0; | 548 | return 0; |
543 | } | 549 | } |
544 | 550 | ||
551 | struct cx8802_dev * cx8802_get_device(struct inode *inode) | ||
552 | { | ||
553 | int minor = iminor(inode); | ||
554 | struct cx8802_dev *h = NULL; | ||
555 | struct list_head *list; | ||
556 | |||
557 | list_for_each(list,&cx8802_devlist) { | ||
558 | h = list_entry(list, struct cx8802_dev, devlist); | ||
559 | if (h->mpeg_dev->minor == minor) | ||
560 | return h; | ||
561 | } | ||
562 | |||
563 | return NULL; | ||
564 | } | ||
565 | |||
566 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype) | ||
567 | { | ||
568 | struct cx8802_dev *h = NULL; | ||
569 | struct cx8802_driver *d = NULL; | ||
570 | struct list_head *list; | ||
571 | struct list_head *list2; | ||
572 | |||
573 | list_for_each(list,&cx8802_devlist) { | ||
574 | h = list_entry(list, struct cx8802_dev, devlist); | ||
575 | if (h != dev) | ||
576 | continue; | ||
577 | |||
578 | list_for_each(list2, &h->drvlist.devlist) { | ||
579 | d = list_entry(list2, struct cx8802_driver, devlist); | ||
580 | |||
581 | /* only unregister the correct driver type */ | ||
582 | if (d->type_id == btype) { | ||
583 | return d; | ||
584 | } | ||
585 | } | ||
586 | } | ||
587 | |||
588 | return NULL; | ||
589 | } | ||
590 | |||
591 | /* Driver asked for hardware access. */ | ||
592 | int cx8802_request_acquire(struct cx8802_driver *drv) | ||
593 | { | ||
594 | struct cx88_core *core = drv->core; | ||
595 | |||
596 | /* Fail a request for hardware if the device is busy. */ | ||
597 | if (core->active_type_id != CX88_BOARD_NONE) | ||
598 | return -EBUSY; | ||
599 | |||
600 | if (drv->advise_acquire) | ||
601 | { | ||
602 | core->active_type_id = drv->type_id; | ||
603 | drv->advise_acquire(drv); | ||
604 | |||
605 | mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO)); | ||
606 | } | ||
607 | |||
608 | return 0; | ||
609 | } | ||
610 | |||
611 | /* Driver asked to release hardware. */ | ||
612 | int cx8802_request_release(struct cx8802_driver *drv) | ||
613 | { | ||
614 | struct cx88_core *core = drv->core; | ||
615 | |||
616 | if (drv->advise_release) | ||
617 | { | ||
618 | drv->advise_release(drv); | ||
619 | core->active_type_id = CX88_BOARD_NONE; | ||
620 | mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO)); | ||
621 | } | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static int cx8802_check_driver(struct cx8802_driver *drv) | ||
627 | { | ||
628 | if (drv == NULL) | ||
629 | return -ENODEV; | ||
630 | |||
631 | if ((drv->type_id != CX88_MPEG_DVB) && | ||
632 | (drv->type_id != CX88_MPEG_BLACKBIRD)) | ||
633 | return -EINVAL; | ||
634 | |||
635 | if ((drv->hw_access != CX8802_DRVCTL_SHARED) && | ||
636 | (drv->hw_access != CX8802_DRVCTL_EXCLUSIVE)) | ||
637 | return -EINVAL; | ||
638 | |||
639 | if ((drv->probe == NULL) || | ||
640 | (drv->remove == NULL) || | ||
641 | (drv->advise_acquire == NULL) || | ||
642 | (drv->advise_release == NULL)) | ||
643 | return -EINVAL; | ||
644 | |||
645 | return 0; | ||
646 | } | ||
647 | |||
648 | int cx8802_register_driver(struct cx8802_driver *drv) | ||
649 | { | ||
650 | struct cx8802_dev *h; | ||
651 | struct cx8802_driver *driver; | ||
652 | struct list_head *list; | ||
653 | int err = 0, i = 0; | ||
654 | |||
655 | printk(KERN_INFO "%s() ->registering driver type=%s access=%s\n", __FUNCTION__ , | ||
656 | drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird", | ||
657 | drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive"); | ||
658 | |||
659 | if ((err = cx8802_check_driver(drv)) != 0) { | ||
660 | printk(KERN_INFO "%s() cx8802_driver is invalid\n", __FUNCTION__ ); | ||
661 | return err; | ||
662 | } | ||
663 | |||
664 | list_for_each(list,&cx8802_devlist) { | ||
665 | h = list_entry(list, struct cx8802_dev, devlist); | ||
666 | |||
667 | printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d]\n", | ||
668 | h->core->name,h->pci->subsystem_vendor, | ||
669 | h->pci->subsystem_device,cx88_boards[h->core->board].name, | ||
670 | h->core->board); | ||
671 | |||
672 | /* Bring up a new struct for each driver instance */ | ||
673 | driver = kzalloc(sizeof(*drv),GFP_KERNEL); | ||
674 | if (driver == NULL) | ||
675 | return -ENOMEM; | ||
676 | |||
677 | /* Snapshot of the driver registration data */ | ||
678 | drv->core = h->core; | ||
679 | drv->suspend = cx8802_suspend_common; | ||
680 | drv->resume = cx8802_resume_common; | ||
681 | drv->request_acquire = cx8802_request_acquire; | ||
682 | drv->request_release = cx8802_request_release; | ||
683 | memcpy(driver, drv, sizeof(*driver)); | ||
684 | |||
685 | err = drv->probe(driver); | ||
686 | if (err == 0) { | ||
687 | i++; | ||
688 | mutex_lock(&drv->core->lock); | ||
689 | list_add_tail(&driver->devlist,&h->drvlist.devlist); | ||
690 | mutex_unlock(&drv->core->lock); | ||
691 | } else { | ||
692 | printk(KERN_ERR "%s() ->probe failed err = %d\n", __FUNCTION__, err); | ||
693 | } | ||
694 | |||
695 | } | ||
696 | if (i == 0) | ||
697 | err = -ENODEV; | ||
698 | else | ||
699 | err = 0; | ||
700 | |||
701 | return err; | ||
702 | } | ||
703 | |||
704 | int cx8802_unregister_driver(struct cx8802_driver *drv) | ||
705 | { | ||
706 | struct cx8802_dev *h; | ||
707 | struct cx8802_driver *d; | ||
708 | struct list_head *list; | ||
709 | struct list_head *list2, *q; | ||
710 | int err = 0, i = 0; | ||
711 | |||
712 | printk(KERN_INFO "%s() ->unregistering driver type=%s\n", __FUNCTION__ , | ||
713 | drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird"); | ||
714 | |||
715 | list_for_each(list,&cx8802_devlist) { | ||
716 | i++; | ||
717 | h = list_entry(list, struct cx8802_dev, devlist); | ||
718 | |||
719 | printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d]\n", | ||
720 | h->core->name,h->pci->subsystem_vendor, | ||
721 | h->pci->subsystem_device,cx88_boards[h->core->board].name, | ||
722 | h->core->board); | ||
723 | |||
724 | list_for_each_safe(list2, q, &h->drvlist.devlist) { | ||
725 | d = list_entry(list2, struct cx8802_driver, devlist); | ||
726 | |||
727 | /* only unregister the correct driver type */ | ||
728 | if (d->type_id != drv->type_id) | ||
729 | continue; | ||
730 | |||
731 | err = d->remove(d); | ||
732 | if (err == 0) { | ||
733 | mutex_lock(&drv->core->lock); | ||
734 | list_del(list2); | ||
735 | mutex_unlock(&drv->core->lock); | ||
736 | } else | ||
737 | printk(KERN_ERR "%s() ->remove failed err = %d\n", __FUNCTION__, err); | ||
738 | |||
739 | } | ||
740 | |||
741 | } | ||
742 | |||
743 | return err; | ||
744 | } | ||
745 | |||
545 | /* ----------------------------------------------------------- */ | 746 | /* ----------------------------------------------------------- */ |
747 | static int __devinit cx8802_probe(struct pci_dev *pci_dev, | ||
748 | const struct pci_device_id *pci_id) | ||
749 | { | ||
750 | struct cx8802_dev *dev; | ||
751 | struct cx88_core *core; | ||
752 | int err; | ||
753 | |||
754 | /* general setup */ | ||
755 | core = cx88_core_get(pci_dev); | ||
756 | if (NULL == core) | ||
757 | return -EINVAL; | ||
546 | 758 | ||
759 | printk("%s/2: cx2388x 8802 Driver Manager\n", core->name); | ||
760 | |||
761 | err = -ENODEV; | ||
762 | if (!cx88_boards[core->board].mpeg) | ||
763 | goto fail_core; | ||
764 | |||
765 | err = -ENOMEM; | ||
766 | dev = kzalloc(sizeof(*dev),GFP_KERNEL); | ||
767 | if (NULL == dev) | ||
768 | goto fail_core; | ||
769 | dev->pci = pci_dev; | ||
770 | dev->core = core; | ||
771 | |||
772 | err = cx8802_init_common(dev); | ||
773 | if (err != 0) | ||
774 | goto fail_free; | ||
775 | |||
776 | INIT_LIST_HEAD(&dev->drvlist.devlist); | ||
777 | list_add_tail(&dev->devlist,&cx8802_devlist); | ||
778 | |||
779 | /* Maintain a reference so cx88-video can query the 8802 device. */ | ||
780 | core->dvbdev = dev; | ||
781 | return 0; | ||
782 | |||
783 | fail_free: | ||
784 | kfree(dev); | ||
785 | fail_core: | ||
786 | cx88_core_put(core,pci_dev); | ||
787 | return err; | ||
788 | } | ||
789 | |||
790 | static void __devexit cx8802_remove(struct pci_dev *pci_dev) | ||
791 | { | ||
792 | struct cx8802_dev *dev; | ||
793 | struct cx8802_driver *h; | ||
794 | struct list_head *list; | ||
795 | |||
796 | dev = pci_get_drvdata(pci_dev); | ||
797 | |||
798 | dprintk( 1, "%s\n", __FUNCTION__); | ||
799 | |||
800 | list_for_each(list,&dev->drvlist.devlist) { | ||
801 | h = list_entry(list, struct cx8802_driver, devlist); | ||
802 | dprintk( 1, " ->driver\n"); | ||
803 | if (h->remove == NULL) { | ||
804 | printk(KERN_ERR "%s .. skipping driver, no probe function\n", __FUNCTION__); | ||
805 | continue; | ||
806 | } | ||
807 | printk(KERN_INFO "%s .. Removing driver type %d\n", __FUNCTION__, h->type_id); | ||
808 | cx8802_unregister_driver(h); | ||
809 | list_del(&dev->drvlist.devlist); | ||
810 | } | ||
811 | |||
812 | /* Destroy any 8802 reference. */ | ||
813 | dev->core->dvbdev = NULL; | ||
814 | |||
815 | /* common */ | ||
816 | cx8802_fini_common(dev); | ||
817 | cx88_core_put(dev->core,dev->pci); | ||
818 | kfree(dev); | ||
819 | } | ||
820 | |||
821 | static struct pci_device_id cx8802_pci_tbl[] = { | ||
822 | { | ||
823 | .vendor = 0x14f1, | ||
824 | .device = 0x8802, | ||
825 | .subvendor = PCI_ANY_ID, | ||
826 | .subdevice = PCI_ANY_ID, | ||
827 | },{ | ||
828 | /* --- end of list --- */ | ||
829 | } | ||
830 | }; | ||
831 | MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl); | ||
832 | |||
833 | static struct pci_driver cx8802_pci_driver = { | ||
834 | .name = "cx88-mpeg driver manager", | ||
835 | .id_table = cx8802_pci_tbl, | ||
836 | .probe = cx8802_probe, | ||
837 | .remove = __devexit_p(cx8802_remove), | ||
838 | }; | ||
839 | |||
840 | static int cx8802_init(void) | ||
841 | { | ||
842 | printk(KERN_INFO "cx2388x cx88-mpeg Driver Manager version %d.%d.%d loaded\n", | ||
843 | (CX88_VERSION_CODE >> 16) & 0xff, | ||
844 | (CX88_VERSION_CODE >> 8) & 0xff, | ||
845 | CX88_VERSION_CODE & 0xff); | ||
846 | #ifdef SNAPSHOT | ||
847 | printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", | ||
848 | SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); | ||
849 | #endif | ||
850 | return pci_register_driver(&cx8802_pci_driver); | ||
851 | } | ||
852 | |||
853 | static void cx8802_fini(void) | ||
854 | { | ||
855 | pci_unregister_driver(&cx8802_pci_driver); | ||
856 | } | ||
857 | |||
858 | module_init(cx8802_init); | ||
859 | module_exit(cx8802_fini); | ||
547 | EXPORT_SYMBOL(cx8802_buf_prepare); | 860 | EXPORT_SYMBOL(cx8802_buf_prepare); |
548 | EXPORT_SYMBOL(cx8802_buf_queue); | 861 | EXPORT_SYMBOL(cx8802_buf_queue); |
549 | EXPORT_SYMBOL(cx8802_cancel_buffers); | 862 | EXPORT_SYMBOL(cx8802_cancel_buffers); |
@@ -551,9 +864,10 @@ EXPORT_SYMBOL(cx8802_cancel_buffers); | |||
551 | EXPORT_SYMBOL(cx8802_init_common); | 864 | EXPORT_SYMBOL(cx8802_init_common); |
552 | EXPORT_SYMBOL(cx8802_fini_common); | 865 | EXPORT_SYMBOL(cx8802_fini_common); |
553 | 866 | ||
554 | EXPORT_SYMBOL(cx8802_suspend_common); | 867 | EXPORT_SYMBOL(cx8802_register_driver); |
555 | EXPORT_SYMBOL(cx8802_resume_common); | 868 | EXPORT_SYMBOL(cx8802_unregister_driver); |
556 | 869 | EXPORT_SYMBOL(cx8802_get_device); | |
870 | EXPORT_SYMBOL(cx8802_get_driver); | ||
557 | /* ----------------------------------------------------------- */ | 871 | /* ----------------------------------------------------------- */ |
558 | /* | 872 | /* |
559 | * Local variables: | 873 | * Local variables: |
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 58ba9f773524..3482e0114d43 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c | |||
@@ -143,19 +143,6 @@ static void set_audio_finish(struct cx88_core *core, u32 ctl) | |||
143 | cx88_start_audio_dma(core); | 143 | cx88_start_audio_dma(core); |
144 | 144 | ||
145 | if (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) { | 145 | if (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) { |
146 | /* sets sound input from external adc */ | ||
147 | switch (core->board) { | ||
148 | case CX88_BOARD_HAUPPAUGE_ROSLYN: | ||
149 | case CX88_BOARD_KWORLD_MCE200_DELUXE: | ||
150 | case CX88_BOARD_KWORLD_HARDWARE_MPEG_TV_XPERT: | ||
151 | case CX88_BOARD_PIXELVIEW_PLAYTV_P7000: | ||
152 | case CX88_BOARD_ASUS_PVR_416: | ||
153 | cx_clear(AUD_CTL, EN_I2SIN_ENABLE); | ||
154 | break; | ||
155 | default: | ||
156 | cx_set(AUD_CTL, EN_I2SIN_ENABLE); | ||
157 | } | ||
158 | |||
159 | cx_write(AUD_I2SINPUTCNTL, 4); | 146 | cx_write(AUD_I2SINPUTCNTL, 4); |
160 | cx_write(AUD_BAUDRATE, 1); | 147 | cx_write(AUD_BAUDRATE, 1); |
161 | /* 'pass-thru mode': this enables the i2s output to the mpeg encoder */ | 148 | /* 'pass-thru mode': this enables the i2s output to the mpeg encoder */ |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 90e298d074d1..8613378428fd 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -454,6 +454,14 @@ static int video_mux(struct cx88_core *core, unsigned int input) | |||
454 | cx_clear(MO_FILTER_ODD, 0x00002020); | 454 | cx_clear(MO_FILTER_ODD, 0x00002020); |
455 | break; | 455 | break; |
456 | } | 456 | } |
457 | |||
458 | if (cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD) { | ||
459 | /* sets sound input from external adc */ | ||
460 | if (INPUT(input)->extadc) | ||
461 | cx_set(AUD_CTL, EN_I2SIN_ENABLE); | ||
462 | else | ||
463 | cx_clear(AUD_CTL, EN_I2SIN_ENABLE); | ||
464 | } | ||
457 | return 0; | 465 | return 0; |
458 | } | 466 | } |
459 | 467 | ||
@@ -1490,6 +1498,30 @@ int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | |||
1490 | mutex_unlock(&core->lock); | 1498 | mutex_unlock(&core->lock); |
1491 | return 0; | 1499 | return 0; |
1492 | } | 1500 | } |
1501 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1502 | /* ioctls to allow direct acces to the cx2388x registers */ | ||
1503 | case VIDIOC_INT_G_REGISTER: | ||
1504 | { | ||
1505 | struct v4l2_register *reg = arg; | ||
1506 | |||
1507 | if (reg->i2c_id != 0) | ||
1508 | return -EINVAL; | ||
1509 | /* cx2388x has a 24-bit register space */ | ||
1510 | reg->val = cx_read(reg->reg&0xffffff); | ||
1511 | return 0; | ||
1512 | } | ||
1513 | case VIDIOC_INT_S_REGISTER: | ||
1514 | { | ||
1515 | struct v4l2_register *reg = arg; | ||
1516 | |||
1517 | if (reg->i2c_id != 0) | ||
1518 | return -EINVAL; | ||
1519 | if (!capable(CAP_SYS_ADMIN)) | ||
1520 | return -EPERM; | ||
1521 | cx_write(reg->reg&0xffffff, reg->val); | ||
1522 | return 0; | ||
1523 | } | ||
1524 | #endif | ||
1493 | 1525 | ||
1494 | default: | 1526 | default: |
1495 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, | 1527 | return v4l_compat_translate_ioctl(inode,file,cmd,arg, |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 3bc91aad4fe5..7054e941f1d7 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -74,6 +74,11 @@ enum cx88_board_type { | |||
74 | CX88_MPEG_BLACKBIRD | 74 | CX88_MPEG_BLACKBIRD |
75 | }; | 75 | }; |
76 | 76 | ||
77 | enum cx8802_board_access { | ||
78 | CX8802_DRVCTL_SHARED = 1, | ||
79 | CX8802_DRVCTL_EXCLUSIVE = 2, | ||
80 | }; | ||
81 | |||
77 | /* ----------------------------------------------------------- */ | 82 | /* ----------------------------------------------------------- */ |
78 | /* tv norms */ | 83 | /* tv norms */ |
79 | 84 | ||
@@ -220,6 +225,7 @@ struct cx88_input { | |||
220 | enum cx88_itype type; | 225 | enum cx88_itype type; |
221 | unsigned int vmux; | 226 | unsigned int vmux; |
222 | u32 gpio0, gpio1, gpio2, gpio3; | 227 | u32 gpio0, gpio1, gpio2, gpio3; |
228 | unsigned int extadc:1; | ||
223 | }; | 229 | }; |
224 | 230 | ||
225 | struct cx88_board { | 231 | struct cx88_board { |
@@ -330,6 +336,7 @@ struct cx88_core { | |||
330 | 336 | ||
331 | /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ | 337 | /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ |
332 | struct cx8802_dev *dvbdev; | 338 | struct cx8802_dev *dvbdev; |
339 | enum cx88_board_type active_type_id; | ||
333 | }; | 340 | }; |
334 | 341 | ||
335 | struct cx8800_dev; | 342 | struct cx8800_dev; |
@@ -405,6 +412,31 @@ struct cx8802_suspend_state { | |||
405 | int disabled; | 412 | int disabled; |
406 | }; | 413 | }; |
407 | 414 | ||
415 | struct cx8802_driver { | ||
416 | struct cx88_core *core; | ||
417 | struct list_head devlist; | ||
418 | |||
419 | /* Type of driver and access required */ | ||
420 | enum cx88_board_type type_id; | ||
421 | enum cx8802_board_access hw_access; | ||
422 | |||
423 | /* MPEG 8802 internal only */ | ||
424 | int (*suspend)(struct pci_dev *pci_dev, pm_message_t state); | ||
425 | int (*resume)(struct pci_dev *pci_dev); | ||
426 | |||
427 | /* MPEG 8802 -> mini driver - Driver probe and configuration */ | ||
428 | int (*probe)(struct cx8802_driver *drv); | ||
429 | int (*remove)(struct cx8802_driver *drv); | ||
430 | |||
431 | /* MPEG 8802 -> mini driver - Access for hardware control */ | ||
432 | int (*advise_acquire)(struct cx8802_driver *drv); | ||
433 | int (*advise_release)(struct cx8802_driver *drv); | ||
434 | |||
435 | /* MPEG 8802 <- mini driver - Access for hardware control */ | ||
436 | int (*request_acquire)(struct cx8802_driver *drv); | ||
437 | int (*request_release)(struct cx8802_driver *drv); | ||
438 | }; | ||
439 | |||
408 | struct cx8802_dev { | 440 | struct cx8802_dev { |
409 | struct cx88_core *core; | 441 | struct cx88_core *core; |
410 | spinlock_t slock; | 442 | spinlock_t slock; |
@@ -439,6 +471,9 @@ struct cx8802_dev { | |||
439 | 471 | ||
440 | /* mpeg params */ | 472 | /* mpeg params */ |
441 | struct cx2341x_mpeg_params params; | 473 | struct cx2341x_mpeg_params params; |
474 | |||
475 | /* List of attached drivers */ | ||
476 | struct cx8802_driver drvlist; | ||
442 | }; | 477 | }; |
443 | 478 | ||
444 | /* ----------------------------------------------------------- */ | 479 | /* ----------------------------------------------------------- */ |
@@ -571,6 +606,11 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t); | |||
571 | void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual); | 606 | void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual); |
572 | int cx88_audio_thread(void *data); | 607 | int cx88_audio_thread(void *data); |
573 | 608 | ||
609 | int cx8802_register_driver(struct cx8802_driver *drv); | ||
610 | int cx8802_unregister_driver(struct cx8802_driver *drv); | ||
611 | struct cx8802_dev * cx8802_get_device(struct inode *inode); | ||
612 | struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype); | ||
613 | |||
574 | /* ----------------------------------------------------------- */ | 614 | /* ----------------------------------------------------------- */ |
575 | /* cx88-input.c */ | 615 | /* cx88-input.c */ |
576 | 616 | ||
@@ -600,6 +640,13 @@ extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio, | |||
600 | extern const u32 cx88_user_ctrls[]; | 640 | extern const u32 cx88_user_ctrls[]; |
601 | extern int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl); | 641 | extern int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl); |
602 | 642 | ||
643 | /* ----------------------------------------------------------- */ | ||
644 | /* cx88-blackbird.c */ | ||
645 | /* used by cx88-ivtv ioctl emulation layer */ | ||
646 | extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file, | ||
647 | unsigned int cmd, void *arg); | ||
648 | extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd); | ||
649 | |||
603 | /* | 650 | /* |
604 | * Local variables: | 651 | * Local variables: |
605 | * c-basic-offset: 8 | 652 | * c-basic-offset: 8 |