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.c178
1 files changed, 109 insertions, 69 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: