vino.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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