aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c178
-rw-r--r--drivers/media/video/cx88/cx88-cards.c2
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c197
-rw-r--r--drivers/media/video/cx88/cx88-mpeg.c344
-rw-r--r--drivers/media/video/cx88/cx88.h46
5 files changed, 591 insertions, 176 deletions
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 46738321adaf..0037188d77d4 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
53static 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
921int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
922 unsigned int cmd, void *arg);
923unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
924
922static unsigned int mpeg_translate_ioctl(unsigned int cmd) 925static unsigned int mpeg_translate_ioctl(unsigned int cmd)
923{ 926{
924 return cmd; 927 return cmd;
@@ -927,33 +930,48 @@ static unsigned int mpeg_translate_ioctl(unsigned int cmd)
927static int mpeg_ioctl(struct inode *inode, struct file *file, 930static 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
934static int mpeg_open(struct inode *inode, struct file *file) 937static 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 dprintk( 1, "%s\n", __FUNCTION__);
942 h = list_entry(list, struct cx8802_dev, devlist); 946
943 if (h->mpeg_dev->minor == minor) 947 dev = cx8802_get_device(inode);
944 dev = h; 948 if (dev == NULL)
945 }
946 if (NULL == dev)
947 return -ENODEV; 949 return -ENODEV;
948 950
949 if (blackbird_initialize_codec(dev) < 0) 951 /* Make sure we can acquire the hardware */
952 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
953 if (drv) {
954 err = drv->request_acquire(drv);
955 if(err != 0) {
956 dprintk(1,"%s: Unable to acquire hardware, %d\n", __FUNCTION__, err);
957 return err;
958 }
959 }
960
961 if (blackbird_initialize_codec(dev) < 0) {
962 if (drv)
963 drv->request_release(drv);
950 return -EINVAL; 964 return -EINVAL;
965 }
951 dprintk(1,"open minor=%d\n",minor); 966 dprintk(1,"open minor=%d\n",minor);
952 967
953 /* allocate + initialize per filehandle data */ 968 /* allocate + initialize per filehandle data */
954 fh = kzalloc(sizeof(*fh),GFP_KERNEL); 969 fh = kzalloc(sizeof(*fh),GFP_KERNEL);
955 if (NULL == fh) 970 if (NULL == fh) {
971 if (drv)
972 drv->request_release(drv);
956 return -ENOMEM; 973 return -ENOMEM;
974 }
957 file->private_data = fh; 975 file->private_data = fh;
958 fh->dev = dev; 976 fh->dev = dev;
959 977
@@ -974,6 +992,8 @@ static int mpeg_open(struct inode *inode, struct file *file)
974static int mpeg_release(struct inode *inode, struct file *file) 992static int mpeg_release(struct inode *inode, struct file *file)
975{ 993{
976 struct cx8802_fh *fh = file->private_data; 994 struct cx8802_fh *fh = file->private_data;
995 struct cx8802_dev *dev = NULL;
996 struct cx8802_driver *drv = NULL;
977 997
978 /* blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */ 998 /* 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, 999 blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
@@ -992,6 +1012,16 @@ static int mpeg_release(struct inode *inode, struct file *file)
992 videobuf_mmap_free(&fh->mpegq); 1012 videobuf_mmap_free(&fh->mpegq);
993 file->private_data = NULL; 1013 file->private_data = NULL;
994 kfree(fh); 1014 kfree(fh);
1015
1016 /* Make sure we release the hardware */
1017 dev = cx8802_get_device(inode);
1018 if (dev == NULL)
1019 return -ENODEV;
1020
1021 drv = cx8802_get_driver(dev, CX88_MPEG_BLACKBIRD);
1022 if (drv)
1023 drv->request_release(drv);
1024
995 return 0; 1025 return 0;
996} 1026}
997 1027
@@ -1043,6 +1073,44 @@ static struct video_device cx8802_mpeg_template =
1043 1073
1044/* ------------------------------------------------------------------ */ 1074/* ------------------------------------------------------------------ */
1045 1075
1076/* The CX8802 MPEG API will call this when we can use the hardware */
1077static int cx8802_blackbird_advise_acquire(struct cx8802_driver *drv)
1078{
1079 struct cx88_core *core = drv->core;
1080 int err = 0;
1081
1082 switch (core->board) {
1083 case CX88_BOARD_HAUPPAUGE_HVR1300:
1084 /* By default, core setup will leave the cx22702 out of reset, on the bus.
1085 * We left the hardware on power up with the cx22702 active.
1086 * We're being given access to re-arrange the GPIOs.
1087 * Take the bus off the cx22702 and put the cx23416 on it.
1088 */
1089 cx_clear(MO_GP0_IO, 0x00000080); /* cx22702 in reset */
1090 cx_set(MO_GP0_IO, 0x00000004); /* Disable the cx22702 */
1091 break;
1092 default:
1093 err = -ENODEV;
1094 }
1095 return err;
1096}
1097
1098/* The CX8802 MPEG API will call this when we need to release the hardware */
1099static int cx8802_blackbird_advise_release(struct cx8802_driver *drv)
1100{
1101 struct cx88_core *core = drv->core;
1102 int err = 0;
1103
1104 switch (core->board) {
1105 case CX88_BOARD_HAUPPAUGE_HVR1300:
1106 /* Exit leaving the cx23416 on the bus */
1107 break;
1108 default:
1109 err = -ENODEV;
1110 }
1111 return err;
1112}
1113
1046static void blackbird_unregister_video(struct cx8802_dev *dev) 1114static void blackbird_unregister_video(struct cx8802_dev *dev)
1047{ 1115{
1048 if (dev->mpeg_dev) { 1116 if (dev->mpeg_dev) {
@@ -1073,28 +1141,23 @@ static int blackbird_register_video(struct cx8802_dev *dev)
1073 1141
1074/* ----------------------------------------------------------- */ 1142/* ----------------------------------------------------------- */
1075 1143
1076static int __devinit blackbird_probe(struct pci_dev *pci_dev, 1144static int cx8802_blackbird_probe(struct cx8802_driver *drv)
1077 const struct pci_device_id *pci_id)
1078{ 1145{
1079 struct cx8802_dev *dev; 1146 struct cx88_core *core = drv->core;
1080 struct cx88_core *core; 1147 struct cx8802_dev *dev = core->dvbdev;
1081 int err; 1148 int err;
1082 1149
1083 /* general setup */ 1150 dprintk( 1, "%s\n", __FUNCTION__);
1084 core = cx88_core_get(pci_dev); 1151 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
1085 if (NULL == core) 1152 core->board,
1086 return -EINVAL; 1153 core->name,
1154 core->pci_bus,
1155 core->pci_slot);
1087 1156
1088 err = -ENODEV; 1157 err = -ENODEV;
1089 if (!(cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD)) 1158 if (!(cx88_boards[core->board].mpeg & CX88_MPEG_BLACKBIRD))
1090 goto fail_core; 1159 goto fail_core;
1091 1160
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; 1161 dev->width = 720;
1099 dev->height = 576; 1162 dev->height = 576;
1100 cx2341x_fill_defaults(&dev->params); 1163 cx2341x_fill_defaults(&dev->params);
@@ -1106,64 +1169,36 @@ static int __devinit blackbird_probe(struct pci_dev *pci_dev,
1106 dev->height = 576; 1169 dev->height = 576;
1107 } 1170 }
1108 1171
1109 err = cx8802_init_common(dev);
1110 if (0 != err)
1111 goto fail_free;
1112
1113 /* blackbird stuff */ 1172 /* blackbird stuff */
1114 printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n", 1173 printk("%s/2: cx23416 based mpeg encoder (blackbird reference design)\n",
1115 core->name); 1174 core->name);
1116 host_setup(dev->core); 1175 host_setup(dev->core);
1117 1176
1118 list_add_tail(&dev->devlist,&cx8802_devlist);
1119 blackbird_register_video(dev); 1177 blackbird_register_video(dev);
1120 1178
1121 /* initial device configuration: needed ? */ 1179 /* initial device configuration: needed ? */
1122 1180
1123 return 0; 1181 return 0;
1124 1182
1125 fail_free:
1126 kfree(dev);
1127 fail_core: 1183 fail_core:
1128 cx88_core_put(core,pci_dev);
1129 return err; 1184 return err;
1130} 1185}
1131 1186
1132static void __devexit blackbird_remove(struct pci_dev *pci_dev) 1187static int cx8802_blackbird_remove(struct cx8802_driver *drv)
1133{ 1188{
1134 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
1135
1136 /* blackbird */ 1189 /* blackbird */
1137 blackbird_unregister_video(dev); 1190 blackbird_unregister_video(drv->core->dvbdev);
1138 list_del(&dev->devlist);
1139 1191
1140 /* common */ 1192 return 0;
1141 cx8802_fini_common(dev);
1142 cx88_core_put(dev->core,dev->pci);
1143 kfree(dev);
1144} 1193}
1145 1194
1146static struct pci_device_id cx8802_pci_tbl[] = { 1195static struct cx8802_driver cx8802_blackbird_driver = {
1147 { 1196 .type_id = CX88_MPEG_BLACKBIRD,
1148 .vendor = 0x14f1, 1197 .hw_access = CX8802_DRVCTL_SHARED,
1149 .device = 0x8802, 1198 .probe = cx8802_blackbird_probe,
1150 .subvendor = PCI_ANY_ID, 1199 .remove = cx8802_blackbird_remove,
1151 .subdevice = PCI_ANY_ID, 1200 .advise_acquire = cx8802_blackbird_advise_acquire,
1152 },{ 1201 .advise_release = cx8802_blackbird_advise_release,
1153 /* --- end of list --- */
1154 }
1155};
1156MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
1157
1158static 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}; 1202};
1168 1203
1169static int blackbird_init(void) 1204static int blackbird_init(void)
@@ -1176,17 +1211,22 @@ static int blackbird_init(void)
1176 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", 1211 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
1177 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); 1212 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1178#endif 1213#endif
1179 return pci_register_driver(&blackbird_pci_driver); 1214 cx88_ioctl_hook = mpeg_do_ioctl;
1215 cx88_ioctl_translator = mpeg_translate_ioctl;
1216 return cx8802_register_driver(&cx8802_blackbird_driver);
1180} 1217}
1181 1218
1182static void blackbird_fini(void) 1219static void blackbird_fini(void)
1183{ 1220{
1184 pci_unregister_driver(&blackbird_pci_driver); 1221 cx8802_unregister_driver(&cx8802_blackbird_driver);
1185} 1222}
1186 1223
1187module_init(blackbird_init); 1224module_init(blackbird_init);
1188module_exit(blackbird_fini); 1225module_exit(blackbird_fini);
1189 1226
1227EXPORT_SYMBOL(cx88_ioctl_hook);
1228EXPORT_SYMBOL(cx88_ioctl_translator);
1229
1190/* ----------------------------------------------------------- */ 1230/* ----------------------------------------------------------- */
1191/* 1231/*
1192 * Local variables: 1232 * Local variables:
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index f764a57c56be..1c5db2070a6e 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -1303,7 +1303,7 @@ struct cx88_board cx88_boards[] = {
1303 .gpio0 = 0xe780, 1303 .gpio0 = 0xe780,
1304 }}, 1304 }},
1305 /* fixme: Add radio support */ 1305 /* fixme: Add radio support */
1306 .mpeg = CX88_MPEG_DVB, 1306 .mpeg = CX88_MPEG_DVB | CX88_MPEG_BLACKBIRD,
1307 }, 1307 },
1308}; 1308};
1309const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards); 1309const unsigned int cx88_bcount = ARRAY_SIZE(cx88_boards);
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 0ef13e7efa2e..8150c09cd2c0 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -57,7 +57,7 @@ module_param(debug, int, 0644);
57MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); 57MODULE_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
@@ -315,20 +315,36 @@ static struct cx22702_config hauppauge_novat_config = {
315 .demod_address = 0x43, 315 .demod_address = 0x43,
316 .output_mode = CX22702_SERIAL_OUTPUT, 316 .output_mode = CX22702_SERIAL_OUTPUT,
317}; 317};
318
319static struct cx22702_config hauppauge_hvr1100_config = { 318static struct cx22702_config hauppauge_hvr1100_config = {
320 .demod_address = 0x63, 319 .demod_address = 0x63,
321 .output_mode = CX22702_SERIAL_OUTPUT, 320 .output_mode = CX22702_SERIAL_OUTPUT,
322}; 321};
323 322static struct cx22702_config hauppauge_hvr3000_config = {
324static struct cx22702_config hauppauge_hvr1300_config = {
325 .demod_address = 0x63, 323 .demod_address = 0x63,
326 .output_mode = CX22702_SERIAL_OUTPUT, 324 .output_mode = CX22702_SERIAL_OUTPUT,
327}; 325};
328 326
329static struct cx22702_config hauppauge_hvr3000_config = { 327static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe,
328 int acquire)
329{
330 struct cx8802_dev *dev= fe->dvb->priv;
331 struct cx8802_driver *drv = NULL;
332 int ret = 0;
333
334 drv = cx8802_get_driver(dev, CX88_MPEG_DVB);
335 if (drv) {
336 if(acquire)
337 ret = drv->request_acquire(drv);
338 else
339 ret = drv->request_release(drv);
340 }
341
342 return ret;
343}
344
345static struct cx22702_config hauppauge_hvr1300_config = {
330 .demod_address = 0x63, 346 .demod_address = 0x63,
331 .output_mode = CX22702_SERIAL_OUTPUT, 347 .output_mode = CX22702_SERIAL_OUTPUT,
332}; 348};
333 349
334static int or51132_set_ts_param(struct dvb_frontend* fe, 350static int or51132_set_ts_param(struct dvb_frontend* fe,
@@ -555,26 +571,6 @@ static int dvb_register(struct cx8802_dev *dev)
555 &dvb_pll_fmd1216me); 571 &dvb_pll_fmd1216me);
556 } 572 }
557 break; 573 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);
572 if (dev->dvb.frontend != NULL) {
573 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
574 &dev->core->i2c_adap,
575 &dvb_pll_fmd1216me);
576 }
577 break;
578 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: 574 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
579 dev->dvb.frontend = dvb_attach(mt352_attach, 575 dev->dvb.frontend = dvb_attach(mt352_attach,
580 &dvico_fusionhdtv, 576 &dvico_fusionhdtv,
@@ -782,6 +778,26 @@ static int dvb_register(struct cx8802_dev *dev)
782 dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; 778 dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage;
783 } 779 }
784 break; 780 break;
781 case CX88_BOARD_HAUPPAUGE_HVR1300:
782 dev->dvb.frontend = dvb_attach(cx22702_attach,
783 &hauppauge_hvr1300_config,
784 &dev->core->i2c_adap);
785 if (dev->dvb.frontend != NULL) {
786 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
787 &dev->core->i2c_adap,
788 &dvb_pll_fmd1216me);
789 }
790 break;
791 case CX88_BOARD_HAUPPAUGE_HVR3000:
792 dev->dvb.frontend = dvb_attach(cx22702_attach,
793 &hauppauge_hvr3000_config,
794 &dev->core->i2c_adap);
795 if (dev->dvb.frontend != NULL) {
796 dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61,
797 &dev->core->i2c_adap,
798 &dvb_pll_fmd1216me);
799 }
800 break;
785 default: 801 default:
786 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 802 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
787 dev->core->name); 803 dev->core->name);
@@ -796,6 +812,8 @@ static int dvb_register(struct cx8802_dev *dev)
796 dev->dvb.frontend->ops.info.frequency_min = dev->core->pll_desc->min; 812 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; 813 dev->dvb.frontend->ops.info.frequency_max = dev->core->pll_desc->max;
798 } 814 }
815 /* Ensure all frontends negotiate bus access */
816 dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
799 817
800 /* Put the analog decoder in standby to keep it quiet */ 818 /* Put the analog decoder in standby to keep it quiet */
801 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); 819 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
@@ -806,37 +824,67 @@ static int dvb_register(struct cx8802_dev *dev)
806 824
807/* ----------------------------------------------------------- */ 825/* ----------------------------------------------------------- */
808 826
809static int __devinit dvb_probe(struct pci_dev *pci_dev, 827/* CX8802 MPEG -> mini driver - We have been given the hardware */
810 const struct pci_device_id *pci_id) 828static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv)
811{ 829{
812 struct cx8802_dev *dev; 830 struct cx88_core *core = drv->core;
813 struct cx88_core *core; 831 int err = 0;
832 dprintk( 1, "%s\n", __FUNCTION__);
833
834 switch (core->board) {
835 case CX88_BOARD_HAUPPAUGE_HVR1300:
836 /* We arrive here with either the cx23416 or the cx22702
837 * on the bus. Take the bus from the cx23416 and enable the
838 * cx22702 demod
839 */
840 cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset and enable */
841 cx_clear(MO_GP0_IO, 0x00000004);
842 udelay(1000);
843 break;
844 default:
845 err = -ENODEV;
846 }
847 return err;
848}
849
850/* CX8802 MPEG -> mini driver - We no longer have the hardware */
851static int cx8802_dvb_advise_release(struct cx8802_driver *drv)
852{
853 struct cx88_core *core = drv->core;
854 int err = 0;
855 dprintk( 1, "%s\n", __FUNCTION__);
856
857 switch (core->board) {
858 case CX88_BOARD_HAUPPAUGE_HVR1300:
859 /* Do Nothing, leave the cx22702 on the bus. */
860 break;
861 default:
862 err = -ENODEV;
863 }
864 return err;
865}
866
867static int cx8802_dvb_probe(struct cx8802_driver *drv)
868{
869 struct cx88_core *core = drv->core;
870 struct cx8802_dev *dev = drv->core->dvbdev;
814 int err; 871 int err;
815 872
816 /* general setup */ 873 dprintk( 1, "%s\n", __FUNCTION__);
817 core = cx88_core_get(pci_dev); 874 dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
818 if (NULL == core) 875 core->board,
819 return -EINVAL; 876 core->name,
877 core->pci_bus,
878 core->pci_slot);
820 879
821 err = -ENODEV; 880 err = -ENODEV;
822 if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB)) 881 if (!(cx88_boards[core->board].mpeg & CX88_MPEG_DVB))
823 goto fail_core; 882 goto fail_core;
824 883
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 884#ifdef HAVE_VP3054_I2C
837 err = vp3054_i2c_probe(dev); 885 err = vp3054_i2c_probe(dev);
838 if (0 != err) 886 if (0 != err)
839 goto fail_free; 887 goto fail_core;
840#endif 888#endif
841 889
842 /* dvb stuff */ 890 /* dvb stuff */
@@ -848,28 +896,16 @@ static int __devinit dvb_probe(struct pci_dev *pci_dev,
848 sizeof(struct cx88_buffer), 896 sizeof(struct cx88_buffer),
849 dev); 897 dev);
850 err = dvb_register(dev); 898 err = dvb_register(dev);
851 if (0 != err) 899 if (err != 0)
852 goto fail_fini; 900 printk("%s dvb_register failed err = %d\n", __FUNCTION__, err);
853
854 /* Maintain a reference to cx88-video can query the 8802 device. */
855 core->dvbdev = dev;
856 return 0;
857 901
858 fail_fini:
859 cx8802_fini_common(dev);
860 fail_free:
861 kfree(dev);
862 fail_core: 902 fail_core:
863 cx88_core_put(core,pci_dev);
864 return err; 903 return err;
865} 904}
866 905
867static void __devexit dvb_remove(struct pci_dev *pci_dev) 906static int cx8802_dvb_remove(struct cx8802_driver *drv)
868{ 907{
869 struct cx8802_dev *dev = pci_get_drvdata(pci_dev); 908 struct cx8802_dev *dev = drv->core->dvbdev;
870
871 /* Destroy any 8802 reference. */
872 dev->core->dvbdev = NULL;
873 909
874 /* dvb */ 910 /* dvb */
875 videobuf_dvb_unregister(&dev->dvb); 911 videobuf_dvb_unregister(&dev->dvb);
@@ -878,33 +914,16 @@ static void __devexit dvb_remove(struct pci_dev *pci_dev)
878 vp3054_i2c_remove(dev); 914 vp3054_i2c_remove(dev);
879#endif 915#endif
880 916
881 /* common */ 917 return 0;
882 cx8802_fini_common(dev);
883 cx88_core_put(dev->core,dev->pci);
884 kfree(dev);
885} 918}
886 919
887static struct pci_device_id cx8802_pci_tbl[] = { 920static struct cx8802_driver cx8802_dvb_driver = {
888 { 921 .type_id = CX88_MPEG_DVB,
889 .vendor = 0x14f1, 922 .hw_access = CX8802_DRVCTL_SHARED,
890 .device = 0x8802, 923 .probe = cx8802_dvb_probe,
891 .subvendor = PCI_ANY_ID, 924 .remove = cx8802_dvb_remove,
892 .subdevice = PCI_ANY_ID, 925 .advise_acquire = cx8802_dvb_advise_acquire,
893 },{ 926 .advise_release = cx8802_dvb_advise_release,
894 /* --- end of list --- */
895 }
896};
897MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
898
899static 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}; 927};
909 928
910static int dvb_init(void) 929static int dvb_init(void)
@@ -917,12 +936,12 @@ static int dvb_init(void)
917 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", 936 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
918 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); 937 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
919#endif 938#endif
920 return pci_register_driver(&dvb_pci_driver); 939 return cx8802_register_driver(&cx8802_dvb_driver);
921} 940}
922 941
923static void dvb_fini(void) 942static void dvb_fini(void)
924{ 943{
925 pci_unregister_driver(&dvb_pci_driver); 944 cx8802_unregister_driver(&cx8802_dvb_driver);
926} 945}
927 946
928module_init(dvb_init); 947module_init(dvb_init);
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c
index 6b23a4e6f66d..6f155713ee02 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);
44MODULE_PARM_DESC(debug,"enable debug messages [mpeg]"); 44MODULE_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
52static LIST_HEAD(cx8802_devlist);
49/* ------------------------------------------------------------------ */ 53/* ------------------------------------------------------------------ */
50 54
51static int cx8802_start_dma(struct cx8802_dev *dev, 55static 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,311 @@ int cx8802_resume_common(struct pci_dev *pci_dev)
542 return 0; 548 return 0;
543} 549}
544 550
551struct 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
566struct 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
576 list_for_each(list2, &h->drvlist.devlist) {
577 d = list_entry(list2, struct cx8802_driver, devlist);
578
579 /* only unregister the correct driver type */
580 if (d->type_id == btype) {
581 return d;
582 }
583 }
584 }
585
586 return NULL;
587}
588
589/* Driver asked for hardware access. */
590int cx8802_request_acquire(struct cx8802_driver *drv)
591{
592 struct cx88_core *core = drv->core;
593
594 /* Fail a request for hardware if the device is busy. */
595 if (core->active_type_id != CX88_BOARD_NONE)
596 return -EBUSY;
597
598 if (drv->advise_acquire)
599 {
600 core->active_type_id = drv->type_id;
601 drv->advise_acquire(drv);
602
603 mpeg_dbg(1,"%s() Post acquire GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
604 }
605
606 return 0;
607}
608
609/* Driver asked to release hardware. */
610int cx8802_request_release(struct cx8802_driver *drv)
611{
612 struct cx88_core *core = drv->core;
613
614 if (drv->advise_release)
615 {
616 drv->advise_release(drv);
617 core->active_type_id = CX88_BOARD_NONE;
618 mpeg_dbg(1,"%s() Post release GPIO=%x\n", __FUNCTION__, cx_read(MO_GP0_IO));
619 }
620
621 return 0;
622}
623
624static int cx8802_check_driver(struct cx8802_driver *drv)
625{
626 if (drv == NULL)
627 return -ENODEV;
628
629 if ((drv->type_id != CX88_MPEG_DVB) &&
630 (drv->type_id != CX88_MPEG_BLACKBIRD))
631 return -EINVAL;
632
633 if ((drv->hw_access != CX8802_DRVCTL_SHARED) &&
634 (drv->hw_access != CX8802_DRVCTL_EXCLUSIVE))
635 return -EINVAL;
636
637 if ((drv->probe == NULL) ||
638 (drv->remove == NULL) ||
639 (drv->advise_acquire == NULL) ||
640 (drv->advise_release == NULL))
641 return -EINVAL;
642
643 return 0;
644}
645
646int cx8802_register_driver(struct cx8802_driver *drv)
647{
648 struct cx8802_dev *h;
649 struct cx8802_driver *driver;
650 struct list_head *list;
651 int err = 0, i = 0;
652
653 printk(KERN_INFO "%s() ->registering driver type=%s access=%s\n", __FUNCTION__ ,
654 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird",
655 drv->hw_access == CX8802_DRVCTL_SHARED ? "shared" : "exclusive");
656
657 if ((err = cx8802_check_driver(drv)) != 0) {
658 printk(KERN_INFO "%s() cx8802_driver is invalid\n", __FUNCTION__ );
659 return err;
660 }
661
662 list_for_each(list,&cx8802_devlist) {
663 i++;
664 h = list_entry(list, struct cx8802_dev, devlist);
665
666 printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d]\n",
667 h->core->name,h->pci->subsystem_vendor,
668 h->pci->subsystem_device,cx88_boards[h->core->board].name,
669 h->core->board);
670
671 /* Bring up a new struct for each driver instance */
672 driver = kzalloc(sizeof(*drv),GFP_KERNEL);
673 if (driver == NULL)
674 return -ENOMEM;
675
676 /* Snapshot of the driver registration data */
677 drv->core = h->core;
678 drv->suspend = cx8802_suspend_common;
679 drv->resume = cx8802_resume_common;
680 drv->request_acquire = cx8802_request_acquire;
681 drv->request_release = cx8802_request_release;
682 memcpy(driver, drv, sizeof(*driver));
683
684 err = drv->probe(driver);
685 if (err == 0) {
686 mutex_lock(&drv->core->lock);
687 list_add_tail(&driver->devlist,&h->drvlist.devlist);
688 mutex_unlock(&drv->core->lock);
689 } else {
690 printk(KERN_ERR "%s() ->probe failed err = %d\n", __FUNCTION__, err);
691 }
692
693 }
694 if (i == 0)
695 err = -ENODEV;
696
697 return err;
698}
699
700int cx8802_unregister_driver(struct cx8802_driver *drv)
701{
702 struct cx8802_dev *h;
703 struct cx8802_driver *d;
704 struct list_head *list;
705 struct list_head *list2, *q;
706 int err = 0, i = 0;
707
708 printk(KERN_INFO "%s() ->unregistering driver type=%s\n", __FUNCTION__ ,
709 drv->type_id == CX88_MPEG_DVB ? "dvb" : "blackbird");
710
711 list_for_each(list,&cx8802_devlist) {
712 i++;
713 h = list_entry(list, struct cx8802_dev, devlist);
714
715 printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d]\n",
716 h->core->name,h->pci->subsystem_vendor,
717 h->pci->subsystem_device,cx88_boards[h->core->board].name,
718 h->core->board);
719
720 list_for_each_safe(list2, q, &h->drvlist.devlist) {
721 d = list_entry(list2, struct cx8802_driver, devlist);
722
723 /* only unregister the correct driver type */
724 if (d->type_id != drv->type_id)
725 continue;
726
727 err = d->remove(d);
728 if (err == 0) {
729 mutex_lock(&drv->core->lock);
730 list_del(list2);
731 mutex_unlock(&drv->core->lock);
732 } else
733 printk(KERN_ERR "%s() ->remove failed err = %d\n", __FUNCTION__, err);
734
735 }
736
737 }
738
739 return err;
740}
741
545/* ----------------------------------------------------------- */ 742/* ----------------------------------------------------------- */
743static int __devinit cx8802_probe(struct pci_dev *pci_dev,
744 const struct pci_device_id *pci_id)
745{
746 struct cx8802_dev *dev;
747 struct cx88_core *core;
748 int err;
749
750 /* general setup */
751 core = cx88_core_get(pci_dev);
752 if (NULL == core)
753 return -EINVAL;
754
755 printk("%s/2: cx2388x 8802 Driver Manager\n", core->name);
756
757 err = -ENODEV;
758 if (!cx88_boards[core->board].mpeg)
759 goto fail_core;
760
761 err = -ENOMEM;
762 dev = kzalloc(sizeof(*dev),GFP_KERNEL);
763 if (NULL == dev)
764 goto fail_core;
765 dev->pci = pci_dev;
766 dev->core = core;
767
768 err = cx8802_init_common(dev);
769 if (err != 0)
770 goto fail_free;
771
772 INIT_LIST_HEAD(&dev->drvlist.devlist);
773 list_add_tail(&dev->devlist,&cx8802_devlist);
546 774
775 /* Maintain a reference so cx88-video can query the 8802 device. */
776 core->dvbdev = dev;
777 return 0;
778
779 fail_free:
780 kfree(dev);
781 fail_core:
782 cx88_core_put(core,pci_dev);
783 return err;
784}
785
786static void __devexit cx8802_remove(struct pci_dev *pci_dev)
787{
788 struct cx8802_dev *dev;
789 struct cx8802_driver *h;
790 struct list_head *list;
791
792 dev = pci_get_drvdata(pci_dev);
793
794 dprintk( 1, "%s\n", __FUNCTION__);
795
796 list_for_each(list,&dev->drvlist.devlist) {
797 h = list_entry(list, struct cx8802_driver, devlist);
798 dprintk( 1, " ->driver\n");
799 if (h->remove == NULL) {
800 printk(KERN_ERR "%s .. skipping driver, no probe function\n", __FUNCTION__);
801 continue;
802 }
803 printk(KERN_INFO "%s .. Removing driver type %d\n", __FUNCTION__, h->type_id);
804 cx8802_unregister_driver(h);
805 list_del(&dev->drvlist.devlist);
806 }
807
808 /* Destroy any 8802 reference. */
809 dev->core->dvbdev = NULL;
810
811 /* common */
812 cx8802_fini_common(dev);
813 cx88_core_put(dev->core,dev->pci);
814 kfree(dev);
815}
816
817static struct pci_device_id cx8802_pci_tbl[] = {
818 {
819 .vendor = 0x14f1,
820 .device = 0x8802,
821 .subvendor = PCI_ANY_ID,
822 .subdevice = PCI_ANY_ID,
823 },{
824 /* --- end of list --- */
825 }
826};
827MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
828
829static struct pci_driver cx8802_pci_driver = {
830 .name = "cx88-mpeg driver manager",
831 .id_table = cx8802_pci_tbl,
832 .probe = cx8802_probe,
833 .remove = __devexit_p(cx8802_remove),
834};
835
836static int cx8802_init(void)
837{
838 printk(KERN_INFO "cx2388x cx88-mpeg Driver Manager version %d.%d.%d loaded\n",
839 (CX88_VERSION_CODE >> 16) & 0xff,
840 (CX88_VERSION_CODE >> 8) & 0xff,
841 CX88_VERSION_CODE & 0xff);
842#ifdef SNAPSHOT
843 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
844 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
845#endif
846 return pci_register_driver(&cx8802_pci_driver);
847}
848
849static void cx8802_fini(void)
850{
851 pci_unregister_driver(&cx8802_pci_driver);
852}
853
854module_init(cx8802_init);
855module_exit(cx8802_fini);
547EXPORT_SYMBOL(cx8802_buf_prepare); 856EXPORT_SYMBOL(cx8802_buf_prepare);
548EXPORT_SYMBOL(cx8802_buf_queue); 857EXPORT_SYMBOL(cx8802_buf_queue);
549EXPORT_SYMBOL(cx8802_cancel_buffers); 858EXPORT_SYMBOL(cx8802_cancel_buffers);
@@ -551,9 +860,10 @@ EXPORT_SYMBOL(cx8802_cancel_buffers);
551EXPORT_SYMBOL(cx8802_init_common); 860EXPORT_SYMBOL(cx8802_init_common);
552EXPORT_SYMBOL(cx8802_fini_common); 861EXPORT_SYMBOL(cx8802_fini_common);
553 862
554EXPORT_SYMBOL(cx8802_suspend_common); 863EXPORT_SYMBOL(cx8802_register_driver);
555EXPORT_SYMBOL(cx8802_resume_common); 864EXPORT_SYMBOL(cx8802_unregister_driver);
556 865EXPORT_SYMBOL(cx8802_get_device);
866EXPORT_SYMBOL(cx8802_get_driver);
557/* ----------------------------------------------------------- */ 867/* ----------------------------------------------------------- */
558/* 868/*
559 * Local variables: 869 * Local variables:
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 3bc91aad4fe5..5980e47aee13 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
77enum 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
@@ -330,6 +335,7 @@ struct cx88_core {
330 335
331 /* cx88-video needs to access cx8802 for hybrid tuner pll access. */ 336 /* cx88-video needs to access cx8802 for hybrid tuner pll access. */
332 struct cx8802_dev *dvbdev; 337 struct cx8802_dev *dvbdev;
338 enum cx88_board_type active_type_id;
333}; 339};
334 340
335struct cx8800_dev; 341struct cx8800_dev;
@@ -405,6 +411,31 @@ struct cx8802_suspend_state {
405 int disabled; 411 int disabled;
406}; 412};
407 413
414struct cx8802_driver {
415 struct cx88_core *core;
416 struct list_head devlist;
417
418 /* Type of driver and access required */
419 enum cx88_board_type type_id;
420 enum cx8802_board_access hw_access;
421
422 /* MPEG 8802 internal only */
423 int (*suspend)(struct pci_dev *pci_dev, pm_message_t state);
424 int (*resume)(struct pci_dev *pci_dev);
425
426 /* MPEG 8802 -> mini driver - Driver probe and configuration */
427 int (*probe)(struct cx8802_driver *drv);
428 int (*remove)(struct cx8802_driver *drv);
429
430 /* MPEG 8802 -> mini driver - Access for hardware control */
431 int (*advise_acquire)(struct cx8802_driver *drv);
432 int (*advise_release)(struct cx8802_driver *drv);
433
434 /* MPEG 8802 <- mini driver - Access for hardware control */
435 int (*request_acquire)(struct cx8802_driver *drv);
436 int (*request_release)(struct cx8802_driver *drv);
437};
438
408struct cx8802_dev { 439struct cx8802_dev {
409 struct cx88_core *core; 440 struct cx88_core *core;
410 spinlock_t slock; 441 spinlock_t slock;
@@ -439,6 +470,9 @@ struct cx8802_dev {
439 470
440 /* mpeg params */ 471 /* mpeg params */
441 struct cx2341x_mpeg_params params; 472 struct cx2341x_mpeg_params params;
473
474 /* List of attached drivers */
475 struct cx8802_driver drvlist;
442}; 476};
443 477
444/* ----------------------------------------------------------- */ 478/* ----------------------------------------------------------- */
@@ -571,6 +605,11 @@ void cx88_get_stereo(struct cx88_core *core, struct v4l2_tuner *t);
571void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual); 605void cx88_set_stereo(struct cx88_core *core, u32 mode, int manual);
572int cx88_audio_thread(void *data); 606int cx88_audio_thread(void *data);
573 607
608int cx8802_register_driver(struct cx8802_driver *drv);
609int cx8802_unregister_driver(struct cx8802_driver *drv);
610struct cx8802_dev * cx8802_get_device(struct inode *inode);
611struct cx8802_driver * cx8802_get_driver(struct cx8802_dev *dev, enum cx88_board_type btype);
612
574/* ----------------------------------------------------------- */ 613/* ----------------------------------------------------------- */
575/* cx88-input.c */ 614/* cx88-input.c */
576 615
@@ -600,6 +639,13 @@ extern int cx88_do_ioctl(struct inode *inode, struct file *file, int radio,
600extern const u32 cx88_user_ctrls[]; 639extern const u32 cx88_user_ctrls[];
601extern int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl); 640extern int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl);
602 641
642/* ----------------------------------------------------------- */
643/* cx88-blackbird.c */
644/* used by cx88-ivtv ioctl emulation layer */
645extern int (*cx88_ioctl_hook)(struct inode *inode, struct file *file,
646 unsigned int cmd, void *arg);
647extern unsigned int (*cx88_ioctl_translator)(unsigned int cmd);
648
603/* 649/*
604 * Local variables: 650 * Local variables:
605 * c-basic-offset: 8 651 * c-basic-offset: 8