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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* Low-level parallel port routines for the Multiface 3 card
  2.  *
  3.  * Author: Joerg Dorchain <joerg@dorchain.net>
  4.  *
  5.  * (C) The elitist m68k Users(TM)
  6.  *
  7.  * based on the existing parport_amiga and lp_mfc
  8.  *
  9.  *
  10.  * From the MFC3 documentation:
  11.  * 
  12.  * Miscellaneous PIA Details
  13.  * -------------------------
  14.  * 
  15.  *  The two open-drain interrupt outputs /IRQA and /IRQB are routed to
  16.  * /INT2 of the Z2 bus.
  17.  * 
  18.  *  The CPU data bus of the PIA (D0-D7) is connected to D8-D15 on the Z2
  19.  * bus. This means that any PIA registers are accessed at even addresses.
  20.  * 
  21.  * Centronics Pin Connections for the PIA
  22.  * --------------------------------------
  23.  * 
  24.  *  The following table shows the connections between the PIA and the
  25.  * Centronics interface connector. These connections implement a single, but
  26.  * very complete, Centronics type interface. The Pin column gives the pin
  27.  * numbers of the PIA. The Centronics pin numbers can be found in the section
  28.  * "Parallel Connectors".
  29.  * 
  30.  * 
  31.  *    Pin | PIA | Dir | Centronics Names
  32.  * -------+-----+-----+---------------------------------------------------------
  33.  *     19 | CB2 | --> | /STROBE (aka /DRDY)
  34.  *  10-17 | PBx | <-> | DATA0 - DATA7
  35.  *     18 | CB1 | <-- | /ACK
  36.  *     40 | CA1 | <-- | BUSY
  37.  *      3 | PA1 | <-- | PAPER-OUT (aka POUT)
  38.  *      4 | PA2 | <-- | SELECTED (aka SEL)
  39.  *      9 | PA7 | --> | /INIT (aka /RESET or /INPUT-PRIME)
  40.  *      6 | PA4 | <-- | /ERROR (aka /FAULT)
  41.  *      7 | PA5 | --> | DIR (aka /SELECT-IN)
  42.  *      8 | PA6 | --> | /AUTO-FEED-XT
  43.  *     39 | CA2 | --> | open
  44.  *      5 | PA3 | <-- | /ACK (same as CB1!)
  45.  *      2 | PA0 | <-- | BUSY (same as CA1!)
  46.  * -------+-----+-----+---------------------------------------------------------
  47.  * 
  48.  * Should be enough to understand some of the driver.
  49.  *
  50.  * Per convention for normal use the port registers are visible.
  51.  * If you need the data direction registers, restore the value in the
  52.  * control register.
  53.  */
  54. #include "multiface.h"
  55. #include <linux/module.h>
  56. #include <linux/init.h>
  57. #include <linux/parport.h>
  58. #include <linux/delay.h>
  59. #include <linux/mc6821.h>
  60. #include <linux/zorro.h>
  61. #include <asm/setup.h>
  62. #include <asm/amigahw.h>
  63. #include <asm/irq.h>
  64. #include <asm/amigaints.h>
  65. /* Maximum Number of Cards supported */
  66. #define MAX_MFC 5
  67. #undef DEBUG
  68. #ifdef DEBUG
  69. #define DPRINTK printk
  70. #else
  71. static inline int DPRINTK(void *nothing, ...) {return 0;}
  72. #endif
  73. static struct parport *this_port[MAX_MFC] = {NULL, };
  74. static volatile int dummy; /* for trigger readds */
  75. #define pia(dev) ((struct pia *)(dev->base))
  76. static struct parport_operations pp_mfc3_ops;
  77. static void mfc3_write_data(struct parport *p, unsigned char data)
  78. {
  79. DPRINTK(KERN_DEBUG "write_data %cn",data);
  80. dummy = pia(p)->pprb; /* clears irq bit */
  81. /* Triggers also /STROBE.*/
  82. pia(p)->pprb = data;
  83. }
  84. static unsigned char mfc3_read_data(struct parport *p)
  85. {
  86. /* clears interrupt bit. Triggers also /STROBE. */
  87. return pia(p)->pprb;
  88. }
  89. static unsigned char control_pc_to_mfc3(unsigned char control)
  90. {
  91. unsigned char ret = 32|64;
  92. if (control & PARPORT_CONTROL_SELECT) /* XXX: What is SELECP? */
  93. ret &= ~32; /* /SELECT_IN */
  94. if (control & PARPORT_CONTROL_INIT) /* INITP */
  95. ret |= 128;
  96. if (control & PARPORT_CONTROL_AUTOFD) /* AUTOLF */
  97. ret &= ~64;
  98. if (control & PARPORT_CONTROL_STROBE) /* Strobe */
  99. /* Handled directly by hardware */;
  100. return ret;
  101. }
  102. static unsigned char control_mfc3_to_pc(unsigned char control)
  103. {
  104. unsigned char ret = PARPORT_CONTROL_STROBE 
  105.   | PARPORT_CONTROL_AUTOFD | PARPORT_CONTROL_SELECT;
  106. if (control & 128) /* /INITP */
  107. ret |= PARPORT_CONTROL_INIT;
  108. if (control & 64) /* /AUTOLF */
  109. ret &= ~PARPORT_CONTROL_AUTOFD;
  110. if (control & 32) /* /SELECT_IN */
  111. ret &= ~PARPORT_CONTROL_SELECT;
  112. return ret;
  113. }
  114. static void mfc3_write_control(struct parport *p, unsigned char control)
  115. {
  116. DPRINTK(KERN_DEBUG "write_control %02xn",control);
  117. pia(p)->ppra = (pia(p)->ppra & 0x1f) | control_pc_to_mfc3(control);
  118. }
  119. static unsigned char mfc3_read_control( struct parport *p)
  120. {
  121. DPRINTK(KERN_DEBUG "read_control n");
  122. return control_mfc3_to_pc(pia(p)->ppra & 0xe0);
  123. }
  124. static unsigned char mfc3_frob_control( struct parport *p, unsigned char mask, unsigned char val)
  125. {
  126. unsigned char old;
  127. DPRINTK(KERN_DEBUG "frob_control mask %02x, value %02xn",mask,val);
  128. old = mfc3_read_control(p);
  129. mfc3_write_control(p, (old & ~mask) ^ val);
  130. return old;
  131. }
  132. #if 0 /* currently unused */
  133. static unsigned char status_pc_to_mfc3(unsigned char status)
  134. {
  135. unsigned char ret = 1;
  136. if (status & PARPORT_STATUS_BUSY) /* Busy */
  137. ret &= ~1;
  138. if (status & PARPORT_STATUS_ACK) /* Ack */
  139. ret |= 8;
  140. if (status & PARPORT_STATUS_PAPEROUT) /* PaperOut */
  141. ret |= 2;
  142. if (status & PARPORT_STATUS_SELECT) /* select */
  143. ret |= 4;
  144. if (status & PARPORT_STATUS_ERROR) /* error */
  145. ret |= 16;
  146. return ret;
  147. }
  148. #endif
  149. static unsigned char status_mfc3_to_pc(unsigned char status)
  150. {
  151. unsigned char ret = PARPORT_STATUS_BUSY;
  152. if (status & 1) /* Busy */
  153. ret &= ~PARPORT_STATUS_BUSY;
  154. if (status & 2) /* PaperOut */
  155. ret |= PARPORT_STATUS_PAPEROUT;
  156. if (status & 4) /* Selected */
  157. ret |= PARPORT_STATUS_SELECT;
  158. if (status & 8) /* Ack */
  159. ret |= PARPORT_STATUS_ACK;
  160. if (status & 16) /* /ERROR */
  161. ret |= PARPORT_STATUS_ERROR;
  162. return ret;
  163. }
  164. #if 0 /* currently unused */
  165. static void mfc3_write_status( struct parport *p, unsigned char status)
  166. {
  167. DPRINTK(KERN_DEBUG "write_status %02xn",status);
  168. pia(p)->ppra = (pia(p)->ppra & 0xe0) | status_pc_to_mfc3(status);
  169. }
  170. #endif
  171. static unsigned char mfc3_read_status(struct parport *p)
  172. {
  173. unsigned char status;
  174. status = status_mfc3_to_pc(pia(p)->ppra & 0x1f);
  175. DPRINTK(KERN_DEBUG "read_status %02xn", status);
  176. return status;
  177. }
  178. #if 0 /* currently unused */
  179. static void mfc3_change_mode( struct parport *p, int m)
  180. {
  181. /* XXX: This port only has one mode, and I am
  182. not sure about the corresponding PC-style mode*/
  183. }
  184. #endif
  185. static int use_cnt = 0;
  186. static void mfc3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  187. {
  188. int i;
  189. for( i = 0; i < MAX_MFC; i++)
  190. if (this_port[i] != NULL)
  191. if (pia(this_port[i])->crb & 128) { /* Board caused interrupt */
  192. dummy = pia(this_port[i])->pprb; /* clear irq bit */
  193. parport_generic_irq(irq, this_port[i], regs);
  194. }
  195. }
  196. static void mfc3_enable_irq(struct parport *p)
  197. {
  198. pia(p)->crb |= PIA_C1_ENABLE_IRQ;
  199. }
  200. static void mfc3_disable_irq(struct parport *p)
  201. {
  202. pia(p)->crb &= ~PIA_C1_ENABLE_IRQ;
  203. }
  204. static void mfc3_data_forward(struct parport *p)
  205. {
  206. DPRINTK(KERN_DEBUG "forwardn");
  207. pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */
  208. pia(p)->pddrb = 255; /* all pins output */
  209. pia(p)->crb |= PIA_DDR; /* make data register visible - default */
  210. }
  211. static void mfc3_data_reverse(struct parport *p)
  212. {
  213. DPRINTK(KERN_DEBUG "reversen");
  214. pia(p)->crb &= ~PIA_DDR; /* make data direction register visible */
  215. pia(p)->pddrb = 0; /* all pins input */
  216. pia(p)->crb |= PIA_DDR; /* make data register visible - default */
  217. }
  218. static void mfc3_init_state(struct pardevice *dev, struct parport_state *s)
  219. {
  220. s->u.amiga.data = 0;
  221. s->u.amiga.datadir = 255;
  222. s->u.amiga.status = 0;
  223. s->u.amiga.statusdir = 0xe0;
  224. }
  225. static void mfc3_save_state(struct parport *p, struct parport_state *s)
  226. {
  227. s->u.amiga.data = pia(p)->pprb;
  228. pia(p)->crb &= ~PIA_DDR;
  229. s->u.amiga.datadir = pia(p)->pddrb;
  230. pia(p)->crb |= PIA_DDR;
  231. s->u.amiga.status = pia(p)->ppra;
  232. pia(p)->cra &= ~PIA_DDR;
  233. s->u.amiga.statusdir = pia(p)->pddrb;
  234. pia(p)->cra |= PIA_DDR;
  235. }
  236. static void mfc3_restore_state(struct parport *p, struct parport_state *s)
  237. {
  238. pia(p)->pprb = s->u.amiga.data;
  239. pia(p)->crb &= ~PIA_DDR;
  240. pia(p)->pddrb = s->u.amiga.datadir;
  241. pia(p)->crb |= PIA_DDR;
  242. pia(p)->ppra = s->u.amiga.status;
  243. pia(p)->cra &= ~PIA_DDR;
  244. pia(p)->pddrb = s->u.amiga.statusdir;
  245. pia(p)->cra |= PIA_DDR;
  246. }
  247. static void mfc3_inc_use_count(void)
  248. {
  249. MOD_INC_USE_COUNT;
  250. }
  251. static void mfc3_dec_use_count(void)
  252. {
  253. MOD_DEC_USE_COUNT;
  254. }
  255. static struct parport_operations pp_mfc3_ops = {
  256. mfc3_write_data,
  257. mfc3_read_data,
  258. mfc3_write_control,
  259. mfc3_read_control,
  260. mfc3_frob_control,
  261. mfc3_read_status,
  262. mfc3_enable_irq,
  263. mfc3_disable_irq,
  264. mfc3_data_forward, 
  265. mfc3_data_reverse, 
  266. mfc3_init_state,
  267. mfc3_save_state,
  268. mfc3_restore_state,
  269. mfc3_inc_use_count,
  270. mfc3_dec_use_count,
  271. parport_ieee1284_epp_write_data,
  272. parport_ieee1284_epp_read_data,
  273. parport_ieee1284_epp_write_addr,
  274. parport_ieee1284_epp_read_addr,
  275. parport_ieee1284_ecp_write_data,
  276. parport_ieee1284_ecp_read_data,
  277. parport_ieee1284_ecp_write_addr,
  278. parport_ieee1284_write_compat,
  279. parport_ieee1284_read_nibble,
  280. parport_ieee1284_read_byte,
  281. };
  282. /* ----------- Initialisation code --------------------------------- */
  283. int __init parport_mfc3_init(void)
  284. {
  285. struct parport *p;
  286. int pias;
  287. struct pia *pp;
  288. struct zorro_dev *z = NULL;
  289. if (!MACH_IS_AMIGA)
  290. return -ENODEV;
  291. while ((z = zorro_find_device(ZORRO_PROD_BSC_MULTIFACE_III, z))) {
  292. unsigned long piabase = z->resource.start+PIABASE;
  293. if (!request_mem_region(piabase, sizeof(struct pia), "PIA"))
  294. continue;
  295. pp = (struct pia *)ZTWO_VADDR(piabase);
  296. pp->crb = 0;
  297. pp->pddrb = 255; /* all data pins output */
  298. pp->crb = PIA_DDR|32|8;
  299. dummy = pp->pddrb; /* reading clears interrupt */
  300. pp->cra = 0;
  301. pp->pddra = 0xe0; /* /RESET,  /DIR ,/AUTO-FEED output */
  302. pp->cra = PIA_DDR;
  303. pp->ppra = 0; /* reset printer */
  304. udelay(10);
  305. pp->ppra = 128;
  306. p = parport_register_port((unsigned long)pp, IRQ_AMIGA_PORTS,
  307.   PARPORT_DMA_NONE, &pp_mfc3_ops);
  308. if (!p)
  309. goto out_port;
  310. if (p->irq != PARPORT_IRQ_NONE) {
  311. if (use_cnt++ == 0)
  312. if (request_irq(IRQ_AMIGA_PORTS, mfc3_interrupt, SA_SHIRQ, p->name, &pp_mfc3_ops))
  313. goto out_irq;
  314. }
  315. this_port[pias++] = p;
  316. printk(KERN_INFO "%s: Multiface III port using irqn", p->name);
  317. /* XXX: set operating mode */
  318. parport_proc_register(p);
  319. p->private_data = (void *)piabase;
  320. parport_announce_port (p);
  321. if (pias >= MAX_MFC)
  322. break;
  323. continue;
  324. out_irq:
  325. parport_unregister_port(p);
  326. out_port:
  327. release_mem_region(piabase, sizeof(struct pia));
  328. }
  329. return pias ? 0 : -ENODEV;
  330. }
  331. void __exit parport_mfc3_exit(void)
  332. {
  333. int i;
  334. for (i = 0; i < MAX_MFC; i++) {
  335. if (!this_port[i])
  336. continue;
  337. if (!this_port[i]->irq != PARPORT_IRQ_NONE) {
  338. if (--use_cnt == 0) 
  339. free_irq(IRQ_AMIGA_PORTS, &pp_mfc3_ops);
  340. }
  341. parport_proc_unregister(this_port[i]);
  342. parport_unregister_port(this_port[i]);
  343. release_mem_region(ZTWO_PADDR(this_port[i]->private_data), sizeof(struct pia));
  344. }
  345. }
  346. MODULE_AUTHOR("Joerg Dorchain <joerg@dorchain.net>");
  347. MODULE_DESCRIPTION("Parport Driver for Multiface 3 expansion cards Paralllel Port");
  348. MODULE_SUPPORTED_DEVICE("Multiface 3 Parallel Port");
  349. module_init(parport_mfc3_init)
  350. module_exit(parport_mfc3_exit)