vino.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /*
  2. * (incomplete) Driver for the VINO (Video In No Out) system found in SGI Indys.
  3. *
  4. * This file is subject to the terms and conditions of the GNU General Public
  5. * License version 2 as published by the Free Software Foundation.
  6. *
  7. * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
  8. */
  9. #include <linux/module.h>
  10. #include <linux/init.h>
  11. #include <linux/types.h>
  12. #include <linux/mm.h>
  13. #include <linux/slab.h>
  14. #include <linux/wrapper.h>
  15. #include <linux/errno.h>
  16. #include <linux/irq.h>
  17. #include <linux/delay.h>
  18. #include <linux/videodev.h>
  19. #include <linux/i2c.h>
  20. #include <linux/i2c-algo-sgi.h>
  21. #include <asm/addrspace.h>
  22. #include <asm/system.h>
  23. #include <asm/bootinfo.h>
  24. #include <asm/pgtable.h>
  25. #include <asm/paccess.h>
  26. #include <asm/io.h>
  27. #include <asm/sgi/ip22.h>
  28. #include <asm/sgi/hpc3.h>
  29. #include <asm/sgi/mc.h>
  30. #include "vino.h"
  31. /* debugging? */
  32. #if 1
  33. #define DEBUG(x...) printk(x);
  34. #else
  35. #define DEBUG(x...)
  36. #endif
  37. /* VINO ASIC registers */
  38. struct sgi_vino *vino;
  39. static const char *vinostr = "VINO IndyCam/TV";
  40. static int threshold_a = 512;
  41. static int threshold_b = 512;
  42. struct vino_device {
  43. struct video_device vdev;
  44. #define VINO_CHAN_A 1
  45. #define VINO_CHAN_B 2
  46. int chan;
  47. };
  48. struct vino_client {
  49. struct i2c_client *driver;
  50. int owner;
  51. };
  52. struct vino_video {
  53. struct vino_device chA;
  54. struct vino_device chB;
  55. struct vino_client decoder;
  56. struct vino_client camera;
  57. struct semaphore input_lock;
  58. /* Loaded into VINO descriptors to clear End Of Descriptors table
  59. * interupt condition */
  60. unsigned long dummy_page;
  61. unsigned int dummy_buf[4] __attribute__((aligned(8)));
  62. };
  63. static struct vino_video *Vino;
  64. unsigned i2c_vino_getctrl(void *data)
  65. {
  66. return vino->i2c_control;
  67. }
  68. void i2c_vino_setctrl(void *data, unsigned val)
  69. {
  70. vino->i2c_control = val;
  71. }
  72. unsigned i2c_vino_rdata(void *data)
  73. {
  74. return vino->i2c_data;
  75. }
  76. void i2c_vino_wdata(void *data, unsigned val)
  77. {
  78. vino->i2c_data = val;
  79. }
  80. static struct i2c_algo_sgi_data i2c_sgi_vino_data =
  81. {
  82. .getctrl = &i2c_vino_getctrl,
  83. .setctrl = &i2c_vino_setctrl,
  84. .rdata = &i2c_vino_rdata,
  85. .wdata = &i2c_vino_wdata,
  86. .xfer_timeout = 200,
  87. .ack_timeout = 1000,
  88. };
  89. /*
  90. * There are two possible clients on VINO I2C bus, so we limit usage only
  91. * to them.
  92. */
  93. static int i2c_vino_client_reg(struct i2c_client *client)
  94. {
  95. int res = 0;
  96. down(&Vino->input_lock);
  97. switch (client->driver->id) {
  98. case I2C_DRIVERID_SAA7191:
  99. if (Vino->decoder.driver)
  100. res = -EBUSY;
  101. else
  102. Vino->decoder.driver = client;
  103. break;
  104. case I2C_DRIVERID_INDYCAM:
  105. if (Vino->camera.driver)
  106. res = -EBUSY;
  107. else
  108. Vino->camera.driver = client;
  109. break;
  110. default:
  111. res = -ENODEV;
  112. }
  113. up(&Vino->input_lock);
  114. return res;
  115. }
  116. static int i2c_vino_client_unreg(struct i2c_client *client)
  117. {
  118. int res = 0;
  119. down(&Vino->input_lock);
  120. if (client == Vino->decoder.driver) {
  121. if (Vino->decoder.owner)
  122. res = -EBUSY;
  123. else
  124. Vino->decoder.driver = NULL;
  125. } else if (client == Vino->camera.driver) {
  126. if (Vino->camera.owner)
  127. res = -EBUSY;
  128. else
  129. Vino->camera.driver = NULL;
  130. }
  131. up(&Vino->input_lock);
  132. return res;
  133. }
  134. static struct i2c_adapter vino_i2c_adapter =
  135. {
  136. .name = "VINO I2C bus",
  137. .id = I2C_HW_SGI_VINO,
  138. .algo_data = &i2c_sgi_vino_data,
  139. .client_register = &i2c_vino_client_reg,
  140. .client_unregister = &i2c_vino_client_unreg,
  141. };
  142. static int vino_i2c_add_bus(void)
  143. {
  144. return i2c_sgi_add_bus(&vino_i2c_adapter);
  145. }
  146. static int vino_i2c_del_bus(void)
  147. {
  148. return i2c_sgi_del_bus(&vino_i2c_adapter);
  149. }
  150. static void vino_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  151. {
  152. }
  153. static int vino_open(struct video_device *dev, int flags)
  154. {
  155. struct vino_device *videv = (struct vino_device *)dev;
  156. return 0;
  157. }
  158. static void vino_close(struct video_device *dev)
  159. {
  160. struct vino_device *videv = (struct vino_device *)dev;
  161. }
  162. static int vino_mmap(struct video_device *dev, const char *adr,
  163. unsigned long size)
  164. {
  165. struct vino_device *videv = (struct vino_device *)dev;
  166. return -EINVAL;
  167. }
  168. static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
  169. {
  170. struct vino_device *videv = (struct vino_device *)dev;
  171. return -EINVAL;
  172. }
  173. static const struct video_device vino_device = {
  174. .owner = THIS_MODULE,
  175. .type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE,
  176. .hardware = VID_HARDWARE_VINO,
  177. .name = "VINO",
  178. .open = vino_open,
  179. .close = vino_close,
  180. .ioctl = vino_ioctl,
  181. .mmap = vino_mmap,
  182. };
  183. static int __init vino_init(void)
  184. {
  185. unsigned long rev;
  186. int i, ret = 0;
  187. /* VINO is Indy specific beast */
  188. if (ip22_is_fullhouse())
  189. return -ENODEV;
  190. /*
  191. * VINO is in the EISA address space, so the sysid register will tell
  192. * us if the EISA_PRESENT pin on MC has been pulled low.
  193. *
  194. * If EISA_PRESENT is not set we definitely don't have a VINO equiped
  195. * system.
  196. */
  197. if (!(sgimc->systemid & SGIMC_SYSID_EPRESENT)) {
  198. printk(KERN_ERR "VINO not found\n");
  199. return -ENODEV;
  200. }
  201. vino = (struct sgi_vino *)ioremap(VINO_BASE, sizeof(struct sgi_vino));
  202. if (!vino)
  203. return -EIO;
  204. /* Okay, once we know that VINO is present we'll read its revision
  205. * safe way. One never knows... */
  206. if (get_dbe(rev, &(vino->rev_id))) {
  207. printk(KERN_ERR "VINO: failed to read revision register\n");
  208. ret = -ENODEV;
  209. goto out_unmap;
  210. }
  211. if (VINO_ID_VALUE(rev) != VINO_CHIP_ID) {
  212. printk(KERN_ERR "VINO is not VINO (Rev/ID: 0x%04lx)\n", rev);
  213. ret = -ENODEV;
  214. goto out_unmap;
  215. }
  216. printk(KERN_INFO "VINO Rev: 0x%02lx\n", VINO_REV_NUM(rev));
  217. Vino = (struct vino_video *)
  218. kmalloc(sizeof(struct vino_video), GFP_KERNEL);
  219. if (!Vino) {
  220. ret = -ENOMEM;
  221. goto out_unmap;
  222. }
  223. Vino->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
  224. if (!Vino->dummy_page) {
  225. ret = -ENOMEM;
  226. goto out_free_vino;
  227. }
  228. for (i = 0; i < 4; i++)
  229. Vino->dummy_buf[i] = PHYSADDR(Vino->dummy_page);
  230. vino->control = 0;
  231. /* prevent VINO from throwing spurious interrupts */
  232. vino->a.next_4_desc = PHYSADDR(Vino->dummy_buf);
  233. vino->b.next_4_desc = PHYSADDR(Vino->dummy_buf);
  234. udelay(5);
  235. vino->intr_status = 0;
  236. /* set threshold level */
  237. vino->a.fifo_thres = threshold_a;
  238. vino->b.fifo_thres = threshold_b;
  239. init_MUTEX(&Vino->input_lock);
  240. if (request_irq(SGI_VINO_IRQ, vino_interrupt, 0, vinostr, NULL)) {
  241. printk(KERN_ERR "VINO: irq%02d registration failed\n",
  242. SGI_VINO_IRQ);
  243. ret = -EAGAIN;
  244. goto out_free_page;
  245. }
  246. ret = vino_i2c_add_bus();
  247. if (ret) {
  248. printk(KERN_ERR "VINO: I2C bus registration failed\n");
  249. goto out_free_irq;
  250. }
  251. if (video_register_device(&Vino->chA.vdev, VFL_TYPE_GRABBER, -1) < 0) {
  252. printk("%s, chnl %d: device registration failed.\n",
  253. Vino->chA.vdev.name, Vino->chA.chan);
  254. ret = -EINVAL;
  255. goto out_i2c_del_bus;
  256. }
  257. if (video_register_device(&Vino->chB.vdev, VFL_TYPE_GRABBER, -1) < 0) {
  258. printk("%s, chnl %d: device registration failed.\n",
  259. Vino->chB.vdev.name, Vino->chB.chan);
  260. ret = -EINVAL;
  261. goto out_unregister_vdev;
  262. }
  263. return 0;
  264. out_unregister_vdev:
  265. video_unregister_device(&Vino->chA.vdev);
  266. out_i2c_del_bus:
  267. vino_i2c_del_bus();
  268. out_free_irq:
  269. free_irq(SGI_VINO_IRQ, NULL);
  270. out_free_page:
  271. free_page(Vino->dummy_page);
  272. out_free_vino:
  273. kfree(Vino);
  274. out_unmap:
  275. iounmap(vino);
  276. return ret;
  277. }
  278. static void __exit vino_exit(void)
  279. {
  280. video_unregister_device(&Vino->chA.vdev);
  281. video_unregister_device(&Vino->chB.vdev);
  282. vino_i2c_del_bus();
  283. free_irq(SGI_VINO_IRQ, NULL);
  284. free_page(Vino->dummy_page);
  285. kfree(Vino);
  286. iounmap(vino);
  287. }
  288. module_init(vino_init);
  289. module_exit(vino_exit);
  290. MODULE_DESCRIPTION("Video4Linux driver for SGI Indy VINO (IndyCam)");
  291. MODULE_LICENSE("GPL");