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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: parport_sunbpp.c,v 1.12 2001/05/26 03:01:42 davem Exp $
  2.  * Parallel-port routines for Sun architecture
  3.  * 
  4.  * Author: Derrick J. Brashear <shadow@dementia.org>
  5.  *
  6.  * based on work by:
  7.  *          Phil Blundell <Philip.Blundell@pobox.com>
  8.  *          Tim Waugh <tim@cyberelk.demon.co.uk>
  9.  *     Jose Renau <renau@acm.org>
  10.  *          David Campbell <campbell@tirian.che.curtin.edu.au>
  11.  *          Grant Guenther <grant@torque.net>
  12.  *          Eddie C. Dost <ecd@skynet.be>
  13.  *          Stephen Williams (steve@icarus.com)
  14.  *          Gus Baldauf (gbaldauf@ix.netcom.com)
  15.  *          Peter Zaitcev
  16.  *          Tom Dyas
  17.  */
  18. #include <linux/string.h>
  19. #include <linux/module.h>
  20. #include <linux/delay.h>
  21. #include <linux/errno.h>
  22. #include <linux/ioport.h>
  23. #include <linux/kernel.h>
  24. #include <linux/slab.h>
  25. #include <linux/init.h>
  26. #include <linux/parport.h>
  27. #include <asm/ptrace.h>
  28. #include <linux/interrupt.h>
  29. #include <asm/io.h>
  30. #include <asm/oplib.h>           /* OpenProm Library */
  31. #include <asm/sbus.h>
  32. #include <asm/dma.h>             /* BPP uses LSI 64854 for DMA */
  33. #include <asm/irq.h>
  34. #include <asm/sunbpp.h>
  35. #undef __SUNBPP_DEBUG
  36. #ifdef __SUNBPP_DEBUG
  37. #define dprintk(x) printk x
  38. #else
  39. #define dprintk(x)
  40. #endif
  41. static void parport_sunbpp_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  42. {
  43. parport_generic_irq(irq, (struct parport *) dev_id, regs);
  44. }
  45. static void parport_sunbpp_disable_irq(struct parport *p)
  46. {
  47. struct bpp_regs *regs = (struct bpp_regs *)p->base;
  48. u32 tmp;
  49. tmp = sbus_readl(&regs->p_csr);
  50. tmp &= ~DMA_INT_ENAB;
  51. sbus_writel(tmp, &regs->p_csr);
  52. }
  53. static void parport_sunbpp_enable_irq(struct parport *p)
  54. {
  55. struct bpp_regs *regs = (struct bpp_regs *)p->base;
  56. u32 tmp;
  57. tmp = sbus_readl(&regs->p_csr);
  58. tmp |= DMA_INT_ENAB;
  59. sbus_writel(tmp, &regs->p_csr);
  60. }
  61. static void parport_sunbpp_write_data(struct parport *p, unsigned char d)
  62. {
  63. struct bpp_regs *regs = (struct bpp_regs *)p->base;
  64. sbus_writeb(d, &regs->p_dr);
  65. dprintk((KERN_DEBUG "wrote 0x%xn", d));
  66. }
  67. static unsigned char parport_sunbpp_read_data(struct parport *p)
  68. {
  69. struct bpp_regs *regs = (struct bpp_regs *)p->base;
  70. return sbus_readb(&regs->p_dr);
  71. }
  72. #if 0
  73. static void control_pc_to_sunbpp(struct parport *p, unsigned char status)
  74. {
  75. struct bpp_regs *regs = (struct bpp_regs *)p->base;
  76. unsigned char value_tcr = sbus_readb(&regs->p_tcr);
  77. unsigned char value_or = sbus_readb(&regs->p_or);
  78. if (status & PARPORT_CONTROL_STROBE) 
  79. value_tcr |= P_TCR_DS;
  80. if (status & PARPORT_CONTROL_AUTOFD) 
  81. value_or |= P_OR_AFXN;
  82. if (status & PARPORT_CONTROL_INIT) 
  83. value_or |= P_OR_INIT;
  84. if (status & PARPORT_CONTROL_SELECT) 
  85. value_or |= P_OR_SLCT_IN;
  86. sbus_writeb(value_or, &regs->p_or);
  87. sbus_writeb(value_tcr, &regs->p_tcr);
  88. }
  89. #endif
  90. static unsigned char status_sunbpp_to_pc(struct parport *p)
  91. {
  92. struct bpp_regs *regs = (struct bpp_regs *)p->base;
  93. unsigned char bits = 0;
  94. unsigned char value_tcr = sbus_readb(&regs->p_tcr);
  95. unsigned char value_ir = sbus_readb(&regs->p_ir);
  96. if (!(value_ir & P_IR_ERR))
  97. bits |= PARPORT_STATUS_ERROR;
  98. if (!(value_ir & P_IR_SLCT))
  99. bits |= PARPORT_STATUS_SELECT;
  100. if (!(value_ir & P_IR_PE))
  101. bits |= PARPORT_STATUS_PAPEROUT;
  102. if (value_tcr & P_TCR_ACK)
  103. bits |= PARPORT_STATUS_ACK;
  104. if (!(value_tcr & P_TCR_BUSY))
  105. bits |= PARPORT_STATUS_BUSY;
  106. dprintk((KERN_DEBUG "tcr 0x%x ir 0x%xn", regs->p_tcr, regs->p_ir));
  107. dprintk((KERN_DEBUG "read status 0x%xn", bits));
  108. return bits;
  109. }
  110. static unsigned char control_sunbpp_to_pc(struct parport *p)
  111. {
  112. struct bpp_regs *regs = (struct bpp_regs *)p->base;
  113. unsigned char bits = 0;
  114. unsigned char value_tcr = sbus_readb(&regs->p_tcr);
  115. unsigned char value_or = sbus_readb(&regs->p_or);
  116. if (!(value_tcr & P_TCR_DS))
  117. bits |= PARPORT_CONTROL_STROBE;
  118. if (!(value_or & P_OR_AFXN))
  119. bits |= PARPORT_CONTROL_AUTOFD;
  120. if (!(value_or & P_OR_INIT))
  121. bits |= PARPORT_CONTROL_INIT;
  122. if (value_or & P_OR_SLCT_IN)
  123. bits |= PARPORT_CONTROL_SELECT;
  124. dprintk((KERN_DEBUG "tcr 0x%x or 0x%xn", regs->p_tcr, regs->p_or));
  125. dprintk((KERN_DEBUG "read control 0x%xn", bits));
  126. return bits;
  127. }
  128. static unsigned char parport_sunbpp_read_control(struct parport *p)
  129. {
  130. return control_sunbpp_to_pc(p);
  131. }
  132. static unsigned char parport_sunbpp_frob_control(struct parport *p,
  133.  unsigned char mask,
  134.  unsigned char val)
  135. {
  136. struct bpp_regs *regs = (struct bpp_regs *)p->base;
  137. unsigned char value_tcr = sbus_readb(&regs->p_tcr);
  138. unsigned char value_or = sbus_readb(&regs->p_or);
  139. dprintk((KERN_DEBUG "frob1: tcr 0x%x or 0x%xn", regs->p_tcr, regs->p_or));
  140. if (mask & PARPORT_CONTROL_STROBE) {
  141. if (val & PARPORT_CONTROL_STROBE) {
  142. value_tcr &= ~P_TCR_DS;
  143. } else {
  144. value_tcr |= P_TCR_DS;
  145. }
  146. }
  147. if (mask & PARPORT_CONTROL_AUTOFD) {
  148. if (val & PARPORT_CONTROL_AUTOFD) {
  149. value_or &= ~P_OR_AFXN;
  150. } else {
  151. value_or |= P_OR_AFXN;
  152. }
  153. }
  154. if (mask & PARPORT_CONTROL_INIT) {
  155. if (val & PARPORT_CONTROL_INIT) {
  156. value_or &= ~P_OR_INIT;
  157. } else {
  158. value_or |= P_OR_INIT;
  159. }
  160. }
  161. if (mask & PARPORT_CONTROL_SELECT) {
  162. if (val & PARPORT_CONTROL_SELECT) {
  163. value_or |= P_OR_SLCT_IN;
  164. } else {
  165. value_or &= ~P_OR_SLCT_IN;
  166. }
  167. }
  168. sbus_writeb(value_or, &regs->p_or);
  169. sbus_writeb(value_tcr, &regs->p_tcr);
  170. dprintk((KERN_DEBUG "frob2: tcr 0x%x or 0x%xn", regs->p_tcr, regs->p_or));
  171. return parport_sunbpp_read_control(p);
  172. }
  173. static void parport_sunbpp_write_control(struct parport *p, unsigned char d)
  174. {
  175. const unsigned char wm = (PARPORT_CONTROL_STROBE |
  176.   PARPORT_CONTROL_AUTOFD |
  177.   PARPORT_CONTROL_INIT |
  178.   PARPORT_CONTROL_SELECT);
  179. parport_sunbpp_frob_control (p, wm, d & wm);
  180. }
  181. static unsigned char parport_sunbpp_read_status(struct parport *p)
  182. {
  183. return status_sunbpp_to_pc(p);
  184. }
  185. static void parport_sunbpp_data_forward (struct parport *p)
  186. {
  187. struct bpp_regs *regs = (struct bpp_regs *)p->base;
  188. unsigned char value_tcr = sbus_readb(&regs->p_tcr);
  189. dprintk((KERN_DEBUG "forwardn"));
  190. value_tcr &= ~P_TCR_DIR;
  191. sbus_writeb(value_tcr, &regs->p_tcr);
  192. }
  193. static void parport_sunbpp_data_reverse (struct parport *p)
  194. {
  195. struct bpp_regs *regs = (struct bpp_regs *)p->base;
  196. u8 val = sbus_readb(&regs->p_tcr);
  197. dprintk((KERN_DEBUG "reversen"));
  198. val |= P_TCR_DIR;
  199. sbus_writeb(val, &regs->p_tcr);
  200. }
  201. static void parport_sunbpp_init_state(struct pardevice *dev, struct parport_state *s)
  202. {
  203. s->u.pc.ctr = 0xc;
  204. s->u.pc.ecr = 0x0;
  205. }
  206. static void parport_sunbpp_save_state(struct parport *p, struct parport_state *s)
  207. {
  208. s->u.pc.ctr = parport_sunbpp_read_control(p);
  209. }
  210. static void parport_sunbpp_restore_state(struct parport *p, struct parport_state *s)
  211. {
  212. parport_sunbpp_write_control(p, s->u.pc.ctr);
  213. }
  214. static void parport_sunbpp_inc_use_count(void)
  215. {
  216. #ifdef MODULE
  217. MOD_INC_USE_COUNT;
  218. #endif
  219. }
  220. static void parport_sunbpp_dec_use_count(void)
  221. {
  222. #ifdef MODULE
  223. MOD_DEC_USE_COUNT;
  224. #endif
  225. }
  226. static struct parport_operations parport_sunbpp_ops = 
  227. {
  228. parport_sunbpp_write_data,
  229. parport_sunbpp_read_data,
  230. parport_sunbpp_write_control,
  231. parport_sunbpp_read_control,
  232. parport_sunbpp_frob_control,
  233. parport_sunbpp_read_status,
  234. parport_sunbpp_enable_irq,
  235.         parport_sunbpp_disable_irq,
  236.         parport_sunbpp_data_forward,
  237.         parport_sunbpp_data_reverse,
  238.         parport_sunbpp_init_state,
  239.         parport_sunbpp_save_state,
  240.         parport_sunbpp_restore_state,
  241.         parport_sunbpp_inc_use_count,
  242.         parport_sunbpp_dec_use_count,
  243.         parport_ieee1284_epp_write_data,
  244.         parport_ieee1284_epp_read_data,
  245.         parport_ieee1284_epp_write_addr,
  246.         parport_ieee1284_epp_read_addr,
  247.         parport_ieee1284_ecp_write_data,
  248.         parport_ieee1284_ecp_read_data,
  249.         parport_ieee1284_ecp_write_addr,
  250.         parport_ieee1284_write_compat,
  251.         parport_ieee1284_read_nibble,
  252.         parport_ieee1284_read_byte,
  253. };
  254. static int __init init_one_port(struct sbus_dev *sdev)
  255. {
  256. struct parport *p;
  257. /* at least in theory there may be a "we don't dma" case */
  258. struct parport_operations *ops;
  259. unsigned long base;
  260. int irq, dma, err, size;
  261. struct bpp_regs *regs;
  262. unsigned char value_tcr;
  263. dprintk((KERN_DEBUG "init_one_port(%p): ranges, alloc_io, ", sdev));
  264. irq = sdev->irqs[0];
  265. base = sbus_ioremap(&sdev->resource[0], 0,
  266.     sdev->reg_addrs[0].reg_size, 
  267.     "sunbpp");
  268. size = sdev->reg_addrs[0].reg_size;
  269. dma = PARPORT_DMA_NONE;
  270. dprintk(("alloc(ppops), "));
  271. ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL);
  272.         if (!ops) {
  273. sbus_iounmap(base, size);
  274. return 0;
  275.         }
  276.         memcpy (ops, &parport_sunbpp_ops, sizeof (struct parport_operations));
  277. dprintk(("register_portn"));
  278. if (!(p = parport_register_port(base, irq, dma, ops))) {
  279. kfree(ops);
  280. sbus_iounmap(base, size);
  281. return 0;
  282. }
  283. p->size = size;
  284. dprintk((KERN_DEBUG "init_one_port: request_irq(%08x:%p:%x:%s:%p) ",
  285. p->irq, parport_sunbpp_interrupt, SA_SHIRQ, p->name, p));
  286. if ((err = request_irq(p->irq, parport_sunbpp_interrupt,
  287.        SA_SHIRQ, p->name, p)) != 0) {
  288. dprintk(("ERROR %dn", err));
  289. parport_unregister_port(p);
  290. kfree(ops);
  291. sbus_iounmap(base, size);
  292. return err;
  293. } else {
  294. dprintk(("OKn"));
  295. parport_sunbpp_enable_irq(p);
  296. }
  297. regs = (struct bpp_regs *)p->base;
  298. dprintk((KERN_DEBUG "forwardn"));
  299. value_tcr = sbus_readb(&regs->p_tcr);
  300. value_tcr &= ~P_TCR_DIR;
  301. sbus_writeb(value_tcr, &regs->p_tcr);
  302. printk(KERN_INFO "%s: sunbpp at 0x%lxn", p->name, p->base);
  303. parport_proc_register(p);
  304. parport_announce_port (p);
  305. return 1;
  306. }
  307. EXPORT_NO_SYMBOLS;
  308. #ifdef MODULE
  309. int init_module(void)
  310. #else
  311. int __init parport_sunbpp_init(void)
  312. #endif
  313. {
  314.         struct sbus_bus *sbus;
  315.         struct sbus_dev *sdev;
  316. int count = 0;
  317. for_each_sbus(sbus) {
  318. for_each_sbusdev(sdev, sbus) {
  319. if (!strcmp(sdev->prom_name, "SUNW,bpp"))
  320. count += init_one_port(sdev);
  321. }
  322. }
  323. return count ? 0 : -ENODEV;
  324. }
  325. #ifdef MODULE
  326. MODULE_AUTHOR("Derrick J Brashear");
  327. MODULE_DESCRIPTION("Parport Driver for Sparc bidirectional Port");
  328. MODULE_SUPPORTED_DEVICE("Sparc Bidirectional Parallel Port");
  329. void
  330. cleanup_module(void)
  331. {
  332. struct parport *p = parport_enumerate();
  333. while (p) {
  334. struct parport *next = p->next;
  335. if (1/*p->modes & PARPORT_MODE_PCSPP*/) { 
  336. struct parport_operations *ops = p->ops;
  337. if (p->irq != PARPORT_IRQ_NONE) {
  338. parport_sunbpp_disable_irq(p);
  339. free_irq(p->irq, p);
  340. }
  341. sbus_iounmap(p->base, p->size);
  342. parport_proc_unregister(p);
  343. parport_unregister_port(p);
  344. kfree (ops);
  345. }
  346. p = next;
  347. }
  348. }
  349. #endif