aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-blackbird.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/cx88/cx88-blackbird.c')
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c179
1 files changed, 110 insertions, 69 deletions
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
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,49 @@ 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 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)
974static int mpeg_release(struct inode *inode, struct file *file) 993static 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 */
1078static 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 */
1100static 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
1046static void blackbird_unregister_video(struct cx8802_dev *dev) 1115static 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
1076static int __devinit blackbird_probe(struct pci_dev *pci_dev, 1145static 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
1132static void __devexit blackbird_remove(struct pci_dev *pci_dev) 1188static 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
1146static struct pci_device_id cx8802_pci_tbl[] = { 1196static 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};
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}; 1203};
1168 1204
1169static int blackbird_init(void) 1205static 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
1182static void blackbird_fini(void) 1220static void blackbird_fini(void)
1183{ 1221{
1184 pci_unregister_driver(&blackbird_pci_driver); 1222 cx8802_unregister_driver(&cx8802_blackbird_driver);
1185} 1223}
1186 1224
1187module_init(blackbird_init); 1225module_init(blackbird_init);
1188module_exit(blackbird_fini); 1226module_exit(blackbird_fini);
1189 1227
1228EXPORT_SYMBOL(cx88_ioctl_hook);
1229EXPORT_SYMBOL(cx88_ioctl_translator);
1230
1190/* ----------------------------------------------------------- */ 1231/* ----------------------------------------------------------- */
1191/* 1232/*
1192 * Local variables: 1233 * Local variables: