vino.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * (incomplete) Driver for the Vino Video input system found in SGI Indys.
  3.  *
  4.  * Copyright (C) 1999 Ulf Carlsson (ulfc@bun.falkenberg.se)
  5.  *
  6.  * This isn't complete yet, please don't expect any video until I've written
  7.  * some more code.
  8.  */
  9. #include <linux/module.h>
  10. #include <linux/init.h>
  11. #include <linux/types.h>
  12. #include <linux/mm.h>
  13. #include <linux/errno.h>
  14. #include <linux/videodev.h>
  15. #include <asm/addrspace.h>
  16. #include <asm/system.h>
  17. #include "vino.h"
  18. struct vino_device {
  19. struct video_device vdev;
  20. unsigned long chan;
  21. #define VINO_CHAN_A 0
  22. #define VINO_CHAN_B 1
  23. unsigned long flags;
  24. #define VINO_DMA_ACTIVE (1<<0)
  25. };
  26. /* We can actually receive TV and IndyCam input at the same time. Believe it or
  27.  * not..
  28.  */
  29. static struct vino_device vino[2];
  30. /* Those registers have to be accessed by either *one* 64 bit write or *one* 64
  31.  * bit read. We need some asm to fix this. We can't use mips3 as standard
  32.  * because we just save 32 bits at context switch.
  33.  */
  34. static __inline__ unsigned long long vino_reg_read(unsigned long addr)
  35. {
  36. unsigned long long ret __attribute__ ((aligned (64)));
  37. unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
  38. unsigned long flags;
  39. save_and_cli(flags);
  40. __asm__ __volatile__(
  41. ".settmips3nt"
  42. ".settnoatnt"
  43. "ldt$1,(%0)nt"
  44. "sdt$1,(%1)nt"
  45. ".settatnt"
  46. ".settmips0"
  47. :
  48. :"r" (virt_addr), "r" (&ret));
  49. restore_flags(flags);
  50. return ret;
  51. }
  52. static __inline__ void vino_reg_write(unsigned long long value,
  53.       unsigned long addr)
  54. {
  55. unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
  56. unsigned long flags;
  57. /* we might lose the upper parts of the registers which are not saved
  58.  * if there comes an interrupt in our way, play safe */
  59. save_and_cli(flags);
  60. __asm__ __volatile__(
  61. ".settmips3nt"
  62. ".settnoatnt"
  63. "ldt$1,(%0)nt"
  64. "sdt$1,(%1)nt"
  65. ".settatnt"
  66. ".settmips0"
  67. :
  68. :"r" (&value), "r" (virt_addr));
  69. restore_flags(flags);
  70. }
  71. static __inline__ void vino_reg_and(unsigned long long value,
  72.     unsigned long addr)
  73. {
  74. unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
  75. unsigned long tmp, flags;
  76. __save_and_cli(flags);
  77. __asm__ __volatile__(
  78. ".settmips3ttt# vino_reg_andnt"
  79. ".settnoatnt"
  80. "ldt$1, (%1)nt"
  81. "ldt%0, (%2)nt"
  82. "andt$1, $1, %0nt"
  83. "sdt$1, (%1)nt"
  84. ".settatnt"
  85. ".settmips0"
  86. : "=&r" (tmp)
  87. : "r" (virt_addr), "r" (&value));
  88. __restore_flags(flags);
  89. }
  90. static __inline__ void vino_reg_or(unsigned long long value,
  91.    unsigned long addr)
  92. {
  93. unsigned long virt_addr = KSEG1ADDR(addr + VINO_BASE);
  94. unsigned long tmp, flags;
  95. save_and_cli(flags);
  96. __asm__ __volatile__(
  97. ".settmips3nt"
  98. ".settnoatnt"
  99. "ldt$1, (%1)nt"
  100. "ldt%0, (%2)nt"
  101. "ort$1, $1, %0nt"
  102. "sdt$1, (%1)nt"
  103. ".settatnt"
  104. ".settmips0"
  105. : "=&r" (tmp)
  106. : "r" (virt_addr), "r" (&value));
  107. restore_flags(flags);
  108. }
  109. static int vino_dma_setup(void)
  110. {
  111. return 0;
  112. }
  113. static void vino_dma_stop(void)
  114. {
  115. }
  116. static int vino_init(void)
  117. {
  118. unsigned long ret;
  119. unsigned short rev, id;
  120. unsigned long long foo;
  121. unsigned long *bar;
  122. bar = (unsigned long *) &foo;
  123. ret = vino_reg_read(VINO_REVID);
  124. rev = (ret & VINO_REVID_REV_MASK);
  125. id = (ret & VINO_REVID_ID_MASK) >> 4;
  126. printk("Vino: ID:%02hx Rev:%02hxn", id, rev);
  127. foo = vino_reg_read(VINO_A_DESC_DATA0);
  128. printk("0x%lx", bar[0]);
  129. printk("%lx ", bar[1]);
  130. foo = vino_reg_read(VINO_A_DESC_DATA1);
  131. printk("0x%lx", bar[0]);
  132. printk("%lx ", bar[1]);
  133. foo = vino_reg_read(VINO_A_DESC_DATA2);
  134. printk("0x%lx", bar[0]);
  135. printk("%lx ", bar[1]);
  136. foo = vino_reg_read(VINO_A_DESC_DATA3);
  137. printk("0x%lx", bar[0]);
  138. printk("%lxn", bar[1]);
  139. foo = vino_reg_read(VINO_B_DESC_DATA0);
  140. printk("0x%lx", bar[0]);
  141. printk("%lx ", bar[1]);
  142. foo = vino_reg_read(VINO_B_DESC_DATA1);
  143. printk("0x%lx", bar[0]);
  144. printk("%lx ", bar[1]);
  145. foo = vino_reg_read(VINO_B_DESC_DATA2);
  146. printk("0x%lx", bar[0]);
  147. printk("%lx ", bar[1]);
  148. foo = vino_reg_read(VINO_B_DESC_DATA3);
  149. printk("0x%lx", bar[0]);
  150. printk("%lxn", bar[1]);
  151. return 0;
  152. }
  153. static void vino_dma_go(struct vino_device *v)
  154. {
  155. }
  156. /* Reset the vino back to default state */
  157. static void vino_setup(struct vino_device *v)
  158. {
  159. }
  160. static int vino_open(struct video_device *dev, int flags)
  161. {
  162. return 0;
  163. }
  164. static void vino_close(struct video_device *dev)
  165. {
  166. }
  167. static int vino_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
  168. {
  169. return 0;
  170. }
  171. static int vino_mmap(struct video_device *dev, const char *adr,
  172.      unsigned long size)
  173. {
  174. return 0;
  175. }
  176. static struct video_device vino_dev = {
  177. owner: THIS_MODULE,
  178. name: "Vino IndyCam/TV",
  179. type: VID_TYPE_CAPTURE,
  180. hardware: VID_HARDWARE_VINO,
  181. open: vino_open,
  182. close: vino_close,
  183. ioctl: vino_ioctl,
  184. mmap: vino_mmap,
  185. };
  186. int __init init_vino(struct video_device *dev)
  187. {
  188. int err;
  189. err = vino_init();
  190. if (err)
  191. return err;
  192. #if 0
  193. if (video_register_device(&vinodev, VFL_TYPE_GRABBER) == -1) {
  194. return -ENODEV;
  195. }
  196. #endif
  197. return 0;
  198. }
  199. #ifdef MODULE
  200. int init_module(void)
  201. {
  202. int err;
  203. err = vino_init();
  204. if (err)
  205. return err;
  206. return 0;
  207. }
  208. void cleanup_module(void)
  209. {
  210. }
  211. #endif