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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* Low-level parallel port routines for the Atari builtin port
  2.  *
  3.  * Author: Andreas Schwab <schwab@issan.informatik.uni-dortmund.de>
  4.  *
  5.  * Based on parport_amiga.c.
  6.  *
  7.  * The built-in Atari parallel port provides one port at a fixed address
  8.  * with 8 output data lines (D0 - D7), 1 output control line (STROBE)
  9.  * and 1 input status line (BUSY) able to cause an interrupt.
  10.  */
  11. #include <linux/module.h>
  12. #include <linux/init.h>
  13. #include <linux/parport.h>
  14. #include <asm/setup.h>
  15. #include <asm/atarihw.h>
  16. #include <asm/irq.h>
  17. #include <asm/atariints.h>
  18. static struct parport *this_port = NULL;
  19. static unsigned char
  20. parport_atari_read_data(struct parport *p)
  21. {
  22. unsigned long flags;
  23. unsigned char data;
  24. save_flags(flags);
  25. cli();
  26. sound_ym.rd_data_reg_sel = 15;
  27. data = sound_ym.rd_data_reg_sel;
  28. restore_flags(flags);
  29. return data;
  30. }
  31. static void
  32. parport_atari_write_data(struct parport *p, unsigned char data)
  33. {
  34. unsigned long flags;
  35. save_flags(flags);
  36. cli();
  37. sound_ym.rd_data_reg_sel = 15;
  38. sound_ym.wd_data = data;
  39. restore_flags(flags);
  40. }
  41. static unsigned char
  42. parport_atari_read_control(struct parport *p)
  43. {
  44. unsigned long flags;
  45. unsigned char control = 0;
  46. save_flags(flags);
  47. cli();
  48. sound_ym.rd_data_reg_sel = 14;
  49. if (!(sound_ym.rd_data_reg_sel & (1 << 5)))
  50. control = PARPORT_CONTROL_STROBE;
  51. restore_flags(flags);
  52. return control;
  53. }
  54. static void
  55. parport_atari_write_control(struct parport *p, unsigned char control)
  56. {
  57. unsigned long flags;
  58. save_flags(flags);
  59. cli();
  60. sound_ym.rd_data_reg_sel = 14;
  61. if (control & PARPORT_CONTROL_STROBE)
  62. sound_ym.wd_data = sound_ym.rd_data_reg_sel & ~(1 << 5);
  63. else
  64. sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5);
  65. restore_flags(flags);
  66. }
  67. static unsigned char
  68. parport_atari_frob_control(struct parport *p, unsigned char mask,
  69.    unsigned char val)
  70. {
  71. unsigned char old = parport_atari_read_control(p);
  72. parport_atari_write_control(p, (old & ~mask) ^ val);
  73. return old;
  74. }
  75. static unsigned char
  76. parport_atari_read_status(struct parport *p)
  77. {
  78. return ((mfp.par_dt_reg & 1 ? 0 : PARPORT_STATUS_BUSY) |
  79. PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR);
  80. }
  81. static void
  82. parport_atari_init_state(struct pardevice *d, struct parport_state *s)
  83. {
  84. }
  85. static void
  86. parport_atari_save_state(struct parport *p, struct parport_state *s)
  87. {
  88. }
  89. static void
  90. parport_atari_restore_state(struct parport *p, struct parport_state *s)
  91. {
  92. }
  93. static void
  94. parport_atari_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  95. {
  96. parport_generic_irq(irq, (struct parport *) dev_id, regs);
  97. }
  98. static void
  99. parport_atari_enable_irq(struct parport *p)
  100. {
  101. enable_irq(IRQ_MFP_BUSY);
  102. }
  103. static void
  104. parport_atari_disable_irq(struct parport *p)
  105. {
  106. disable_irq(IRQ_MFP_BUSY);
  107. }
  108. static void
  109. parport_atari_data_forward(struct parport *p)
  110. {
  111. unsigned long flags;
  112. save_flags(flags);
  113. cli();
  114. /* Soundchip port B as output. */
  115. sound_ym.rd_data_reg_sel = 7;
  116. sound_ym.wd_data = sound_ym.rd_data_reg_sel | 0x40;
  117. restore_flags(flags);
  118. }
  119. static void
  120. parport_atari_data_reverse(struct parport *p)
  121. {
  122. #if 0 /* too dangerous, can kill sound chip */
  123. unsigned long flags;
  124. save_flags(flags);
  125. cli();
  126. /* Soundchip port B as input. */
  127. sound_ym.rd_data_reg_sel = 7;
  128. sound_ym.wd_data = sound_ym.rd_data_reg_sel & ~0x40;
  129. restore_flags(flags);
  130. #endif
  131. }
  132. static void
  133. parport_atari_inc_use_count(void)
  134. {
  135. MOD_INC_USE_COUNT;
  136. }
  137. static void
  138. parport_atari_dec_use_count(void)
  139. {
  140. MOD_DEC_USE_COUNT;
  141. }
  142. static struct parport_operations parport_atari_ops = {
  143. parport_atari_write_data,
  144. parport_atari_read_data,
  145. parport_atari_write_control,
  146. parport_atari_read_control,
  147. parport_atari_frob_control,
  148. parport_atari_read_status,
  149. parport_atari_enable_irq,
  150. parport_atari_disable_irq,
  151. parport_atari_data_forward,
  152. parport_atari_data_reverse,
  153. parport_atari_init_state,
  154. parport_atari_save_state,
  155. parport_atari_restore_state,
  156. parport_atari_inc_use_count,
  157. parport_atari_dec_use_count,
  158. parport_ieee1284_epp_write_data,
  159. parport_ieee1284_epp_read_data,
  160. parport_ieee1284_epp_write_addr,
  161. parport_ieee1284_epp_read_addr,
  162. parport_ieee1284_ecp_write_data,
  163. parport_ieee1284_ecp_read_data,
  164. parport_ieee1284_ecp_write_addr,
  165. parport_ieee1284_write_compat,
  166. parport_ieee1284_read_nibble,
  167. parport_ieee1284_read_byte,
  168. };
  169. int __init
  170. parport_atari_init(void)
  171. {
  172. struct parport *p;
  173. unsigned long flags;
  174. if (MACH_IS_ATARI) {
  175. save_flags(flags);
  176. cli();
  177. /* Soundchip port A/B as output. */
  178. sound_ym.rd_data_reg_sel = 7;
  179. sound_ym.wd_data = (sound_ym.rd_data_reg_sel & 0x3f) | 0xc0;
  180. /* STROBE high. */
  181. sound_ym.rd_data_reg_sel = 14;
  182. sound_ym.wd_data = sound_ym.rd_data_reg_sel | (1 << 5);
  183. restore_flags(flags);
  184. /* MFP port I0 as input. */
  185. mfp.data_dir &= ~1;
  186. /* MFP port I0 interrupt on high->low edge. */
  187. mfp.active_edge &= ~1;
  188. p = parport_register_port((unsigned long)&sound_ym.wd_data,
  189.   IRQ_MFP_BUSY, PARPORT_DMA_NONE,
  190.   &parport_atari_ops);
  191. if (!p)
  192. return 0;
  193. if (request_irq(IRQ_MFP_BUSY, parport_atari_interrupt,
  194. IRQ_TYPE_SLOW, p->name, p)) {
  195. parport_unregister_port (p);
  196. return 0;
  197. }
  198. this_port = p;
  199. printk(KERN_INFO "%s: Atari built-in port using irqn", p->name);
  200. parport_proc_register(p);
  201. parport_announce_port (p);
  202. return 1;
  203. }
  204. return 0;
  205. }
  206. #ifdef MODULE
  207. MODULE_AUTHOR("Andreas Schwab");
  208. MODULE_DESCRIPTION("Parport Driver for Atari builtin Port");
  209. MODULE_SUPPORTED_DEVICE("Atari builtin Parallel Port");
  210. MODULE_LICENSE("GPL");
  211. int
  212. init_module(void)
  213. {
  214. return parport_atari_init() ? 0 : -ENODEV;
  215. }
  216. void
  217. cleanup_module(void)
  218. {
  219. if (this_port->irq != PARPORT_IRQ_NONE)
  220. free_irq(IRQ_MFP_BUSY, this_port);
  221. parport_proc_unregister(this_port);
  222. parport_unregister_port(this_port);
  223. }
  224. #endif