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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* Low-level parallel port routines for the Amiga built-in port
  2.  *
  3.  * Author: Joerg Dorchain <joerg@dorchain.net>
  4.  *
  5.  * This is a complete rewrite of the code, but based heaviy upon the old
  6.  * lp_intern. code.
  7.  *
  8.  * The built-in Amiga parallel port provides one port at a fixed address
  9.  * with 8 bidirectional data lines (D0 - D7) and 3 bidirectional status
  10.  * lines (BUSY, POUT, SEL), 1 output control line /STROBE (raised automatically
  11.  * in hardware when the data register is accessed), and 1 input control line
  12.  * /ACK, able to cause an interrupt, but both not directly settable by
  13.  * software.
  14.  */
  15. #include <linux/module.h>
  16. #include <linux/init.h>
  17. #include <linux/parport.h>
  18. #include <linux/ioport.h>
  19. #include <asm/setup.h>
  20. #include <asm/amigahw.h>
  21. #include <asm/irq.h>
  22. #include <asm/io.h>
  23. #include <asm/amigaints.h>
  24. #undef DEBUG
  25. #ifdef DEBUG
  26. #define DPRINTK printk
  27. #else
  28. #define DPRINTK(x...) do { } while (0)
  29. #endif
  30. static struct parport *this_port = NULL;
  31. static void amiga_write_data(struct parport *p, unsigned char data)
  32. {
  33. DPRINTK(KERN_DEBUG "write_data %cn",data);
  34. /* Triggers also /STROBE. This behavior cannot be changed */
  35. ciaa.prb = data;
  36. mb();
  37. }
  38. static unsigned char amiga_read_data(struct parport *p)
  39. {
  40. /* Triggers also /STROBE. This behavior cannot be changed */
  41. return ciaa.prb;
  42. }
  43. #if 0
  44. static unsigned char control_pc_to_amiga(unsigned char control)
  45. {
  46. unsigned char ret = 0;
  47. if (control & PARPORT_CONTROL_SELECT) /* XXX: What is SELECP? */
  48. ;
  49. if (control & PARPORT_CONTROL_INIT) /* INITP */
  50. /* reset connected to cpu reset pin */;
  51. if (control & PARPORT_CONTROL_AUTOFD) /* AUTOLF */
  52. /* Not connected */;
  53. if (control & PARPORT_CONTROL_STROBE) /* Strobe */
  54. /* Handled only directly by hardware */;
  55. return ret;
  56. }
  57. #endif
  58. static unsigned char control_amiga_to_pc(unsigned char control)
  59. {
  60. return PARPORT_CONTROL_SELECT |
  61.       PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_STROBE;
  62. /* fake value: interrupt enable, select in, no reset,
  63. no autolf, no strobe - seems to be closest the wiring diagram */
  64. }
  65. static void amiga_write_control(struct parport *p, unsigned char control)
  66. {
  67. DPRINTK(KERN_DEBUG "write_control %02xn",control);
  68. /* No implementation possible */
  69. }
  70. static unsigned char amiga_read_control( struct parport *p)
  71. {
  72. DPRINTK(KERN_DEBUG "read_control n");
  73. return control_amiga_to_pc(0);
  74. }
  75. static unsigned char amiga_frob_control( struct parport *p, unsigned char mask, unsigned char val)
  76. {
  77. unsigned char old;
  78. DPRINTK(KERN_DEBUG "frob_control mask %02x, value %02xn",mask,val);
  79. old = amiga_read_control(p);
  80. amiga_write_control(p, (old & ~mask) ^ val);
  81. return old;
  82. }
  83. #if 0 /* currently unused */
  84. static unsigned char status_pc_to_amiga(unsigned char status)
  85. {
  86. unsigned char ret = 1;
  87. if (status & PARPORT_STATUS_BUSY) /* Busy */
  88. ret &= ~1;
  89. if (status & PARPORT_STATUS_ACK) /* Ack */
  90. /* handled in hardware */;
  91. if (status & PARPORT_STATUS_PAPEROUT) /* PaperOut */
  92. ret |= 2;
  93. if (status & PARPORT_STATUS_SELECT) /* select */
  94. ret |= 4;
  95. if (status & PARPORT_STATUS_ERROR) /* error */
  96. /* not connected */;
  97. return ret;
  98. }
  99. #endif
  100. static unsigned char status_amiga_to_pc(unsigned char status)
  101. {
  102. unsigned char ret = PARPORT_STATUS_BUSY | PARPORT_STATUS_ACK | PARPORT_STATUS_ERROR;
  103. if (status & 1) /* Busy */
  104. ret &= ~PARPORT_STATUS_BUSY;
  105. if (status & 2) /* PaperOut */
  106. ret |= PARPORT_STATUS_PAPEROUT;
  107. if (status & 4) /* Selected */
  108. ret |= PARPORT_STATUS_SELECT;
  109. /* the rest is not connected or handled autonomously in hardware */
  110. return ret;
  111. }
  112. static unsigned char amiga_read_status(struct parport *p)
  113. {
  114. unsigned char status;
  115. status = status_amiga_to_pc(ciab.pra & 7);
  116. DPRINTK(KERN_DEBUG "read_status %02xn", status);
  117. return status;
  118. }
  119. /* as this ports irq handling is already done, we use a generic funktion */
  120. static void amiga_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  121. {
  122. parport_generic_irq(irq, (struct parport *) dev_id, regs);
  123. }
  124. static void amiga_enable_irq(struct parport *p)
  125. {
  126. enable_irq(IRQ_AMIGA_CIAA_FLG);
  127. }
  128. static void amiga_disable_irq(struct parport *p)
  129. {
  130. disable_irq(IRQ_AMIGA_CIAA_FLG);
  131. }
  132. static void amiga_data_forward(struct parport *p)
  133. {
  134. DPRINTK(KERN_DEBUG "forwardn");
  135. ciaa.ddrb = 0xff; /* all pins output */
  136. mb();
  137. }
  138. static void amiga_data_reverse(struct parport *p)
  139. {
  140. DPRINTK(KERN_DEBUG "reversen");
  141. ciaa.ddrb = 0; /* all pins input */
  142. mb();
  143. }
  144. static void amiga_init_state(struct pardevice *dev, struct parport_state *s)
  145. {
  146. s->u.amiga.data = 0;
  147. s->u.amiga.datadir = 255;
  148. s->u.amiga.status = 0;
  149. s->u.amiga.statusdir = 0;
  150. }
  151. static void amiga_save_state(struct parport *p, struct parport_state *s)
  152. {
  153. mb();
  154. s->u.amiga.data = ciaa.prb;
  155. s->u.amiga.datadir = ciaa.ddrb;
  156. s->u.amiga.status = ciab.pra & 7;
  157. s->u.amiga.statusdir = ciab.ddra & 7;
  158. mb();
  159. }
  160. static void amiga_restore_state(struct parport *p, struct parport_state *s)
  161. {
  162. mb();
  163. ciaa.prb = s->u.amiga.data;
  164. ciaa.ddrb = s->u.amiga.datadir;
  165. ciab.pra |= (ciab.pra & 0xf8) | s->u.amiga.status;
  166. ciab.ddra |= (ciab.ddra & 0xf8) | s->u.amiga.statusdir;
  167. mb();
  168. }
  169. static void amiga_inc_use_count(void)
  170. {
  171. MOD_INC_USE_COUNT;
  172. }
  173. static void amiga_dec_use_count(void)
  174. {
  175. MOD_DEC_USE_COUNT;
  176. }
  177. static struct parport_operations pp_amiga_ops = {
  178. amiga_write_data,
  179. amiga_read_data,
  180. amiga_write_control,
  181. amiga_read_control,
  182. amiga_frob_control,
  183. amiga_read_status,
  184. amiga_enable_irq,
  185. amiga_disable_irq,
  186. amiga_data_forward,
  187. amiga_data_reverse,
  188. amiga_init_state,
  189. amiga_save_state,
  190. amiga_restore_state,
  191. amiga_inc_use_count,
  192. amiga_dec_use_count,
  193. parport_ieee1284_epp_write_data,
  194. parport_ieee1284_epp_read_data,
  195. parport_ieee1284_epp_write_addr,
  196. parport_ieee1284_epp_read_addr,
  197. parport_ieee1284_ecp_write_data,
  198. parport_ieee1284_ecp_read_data,
  199. parport_ieee1284_ecp_write_addr,
  200. parport_ieee1284_write_compat,
  201. parport_ieee1284_read_nibble,
  202. parport_ieee1284_read_byte,
  203. };
  204. /* ----------- Initialisation code --------------------------------- */
  205. int __init parport_amiga_init(void)
  206. {
  207. struct parport *p;
  208. int err;
  209. if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_PARALLEL))
  210. return -ENODEV;
  211. err = -EBUSY;
  212. if (!request_mem_region(CIAA_PHYSADDR-1+0x100, 0x100, "parallel"))
  213. goto out_mem;
  214. ciaa.ddrb = 0xff;
  215. ciab.ddra &= 0xf8;
  216. mb();
  217. p = parport_register_port((unsigned long)&ciaa.prb, IRQ_AMIGA_CIAA_FLG,
  218.    PARPORT_DMA_NONE, &pp_amiga_ops);
  219. if (!p)
  220. goto out_port;
  221. err = request_irq(IRQ_AMIGA_CIAA_FLG, amiga_interrupt, 0, p->name, p);
  222. if (err)
  223. goto out_irq;
  224. this_port = p;
  225. printk(KERN_INFO "%s: Amiga built-in port using irqn", p->name);
  226. /* XXX: set operating mode */
  227. parport_proc_register(p);
  228. parport_announce_port(p);
  229. return 0;
  230. out_irq:
  231. parport_unregister_port(p);
  232. out_port:
  233. release_mem_region(CIAA_PHYSADDR-1+0x100, 0x100);
  234. out_mem:
  235. return err;
  236. }
  237. void __exit parport_amiga_exit(void)
  238. {
  239. if (this_port->irq != PARPORT_IRQ_NONE)
  240. free_irq(IRQ_AMIGA_CIAA_FLG, this_port);
  241. parport_proc_unregister(this_port);
  242. parport_unregister_port(this_port);
  243. release_mem_region(CIAA_PHYSADDR-1+0x100, 0x100);
  244. }
  245. MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
  246. MODULE_DESCRIPTION("Parport Driver for Amiga builtin Port");
  247. MODULE_SUPPORTED_DEVICE("Amiga builtin Parallel Port");
  248. MODULE_LICENSE("GPL");
  249. module_init(parport_amiga_init)
  250. module_exit(parport_amiga_exit)