parport.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:15k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: parport.c,v 1.9 2002/05/15 12:30:24 starvik Exp $
  2.  * 
  3.  * Elinux parallel port driver
  4.  * NOTE!
  5.  *   Since par0 shares DMA with ser2 and par 1 shares DMA with ser3
  6.  *   this should be handled if both are enabled at the same time.
  7.  *   THIS IS NOT HANDLED YET!
  8.  *
  9.  * Copyright (c) 2001 Axis Communications AB
  10.  * 
  11.  * Author: Fredrik Hugosson
  12.  *
  13.  */
  14. #include <linux/module.h>
  15. #include <linux/init.h>
  16. #include <linux/parport.h>
  17. #include <linux/ioport.h>
  18. #include <linux/config.h>
  19. #include <linux/errno.h>
  20. #include <linux/kernel.h>
  21. #include <linux/major.h>
  22. #include <linux/sched.h>
  23. #include <linux/slab.h>
  24. #include <linux/interrupt.h>
  25. #include <asm/setup.h>
  26. #include <asm/irq.h>
  27. #include <asm/io.h>
  28. #include <asm/segment.h>
  29. #include <asm/system.h>
  30. #include <asm/svinto.h>
  31. #undef DEBUG
  32. #ifdef DEBUG
  33. #define DPRINTK printk
  34. #else
  35. static inline int DPRINTK(void *nothing, ...) {return 0;}
  36. #endif
  37. /*
  38.  * Etrax100 DMAchannels:
  39.  * Par0 out : DMA2
  40.  * Par0 in  : DMA3
  41.  * Par1 out : DMA4
  42.  * Par1 in  : DMA5
  43.  * NOTE! par0 is shared with ser2 and par1 is shared with ser3 regarding
  44.  *       DMA and DMA irq
  45.  */
  46. //#define CONFIG_PAR0_INT 1
  47. //#define CONFIG_PAR1_INT 1
  48. #define SETF(var, reg, field, val) 
  49. var = (var & ~IO_MASK(##reg##, field)) | IO_FIELD(##reg##, field, val)
  50. #define SETS(var, reg, field, val) 
  51. var = (var & ~IO_MASK(##reg##, field)) | IO_STATE(##reg##, field, val)
  52. struct etrax100par_struct {
  53. /* parallell port control */
  54. volatile u32 *reg_ctrl_data; /* R_PARx_CTRL_DATA */
  55. const volatile u32 *reg_status_data; /* R_PARx_STATUS_DATA */
  56. volatile u32 *reg_config; /* R_PARx_CONFIG */
  57. volatile u32 *reg_delay; /* R_PARx_DELAY */
  58. /* DMA control */
  59. int odma;
  60. unsigned long dma_irq;  /* bitnr in R_IRQ_MASK2 for dmaX_descr */
  61. volatile char *oclrintradr; /* adr to R_DMA_CHx_CLR_INTR, output */
  62. volatile u32 *ofirstadr;   /* adr to R_DMA_CHx_FIRST, output */
  63. volatile char *ocmdadr;     /* adr to R_DMA_CHx_CMD, output */
  64. volatile char *iclrintradr; /* adr to R_DMA_CHx_CLR_INTR, input */
  65. volatile u32 *ifirstadr;   /* adr to R_DMA_CHx_FIRST, input */
  66. volatile char *icmdadr;     /* adr to R_DMA_CHx_CMD, input */
  67. /* Non DMA interrupt stuff */
  68. unsigned long int_irq; /* R_VECT_MASK_RD */
  69. const volatile u32 *irq_mask_rd; /* R_IRQ_MASKX_RD */
  70. volatile u32 *irq_mask_clr; /* R_IRQ_MASKX_RD */
  71. const volatile u32 *irq_read; /* R_IRQ_READX */
  72. volatile u32 *irq_mask_set; /* R_IRQ_MASKX_SET */
  73. unsigned long irq_mask_tx;  /* bitmask in R_IRQ_ for tx (ready) int */
  74. unsigned long irq_mask_rx;  /* bitmask in R_IRQ_ for rx (data) int */
  75. unsigned long irq_mask_ecp_cmd;  /* mask in R_IRQ_ for ecp_cmd int */
  76. unsigned long irq_mask_peri;  /* bitmask in R_IRQ_ for peri int */
  77. int portnr;
  78.   
  79. /* ----- end of fields initialised in port_table[] below ----- */
  80. struct parport *port;
  81.   
  82. /* Shadow registers */
  83. volatile unsigned long reg_ctrl_data_shadow; /* for R_PARx_CTRL_DATA */
  84. volatile unsigned long reg_config_shadow;    /* for R_PARx_CONFIG */
  85. volatile unsigned long reg_delay_shadow;    /* for R_PARx_DELAY */
  86. };
  87. /* Always have the complete structs here, even if the port is not used!
  88.  *  (that way we can index this by the port number)
  89.  */
  90. static struct etrax100par_struct port_table[] = {
  91. R_PAR0_CTRL_DATA,
  92. R_PAR0_STATUS_DATA,
  93. R_PAR0_CONFIG,
  94. R_PAR0_DELAY,
  95. /* DMA interrupt stuff */
  96. 2,
  97. 1U << 4, /* uses DMA 2 and 3 */
  98. R_DMA_CH2_CLR_INTR,
  99. R_DMA_CH2_FIRST,
  100. R_DMA_CH2_CMD,
  101. R_DMA_CH3_CLR_INTR,
  102. R_DMA_CH3_FIRST,
  103. R_DMA_CH3_CMD,
  104. /* Non DMA interrupt stuff */
  105. IO_BITNR(R_VECT_MASK_RD, par0),
  106. R_IRQ_MASK0_RD,
  107. R_IRQ_MASK0_CLR,
  108. R_IRQ_READ0,
  109. R_IRQ_MASK0_SET,
  110. IO_FIELD(R_IRQ_MASK0_RD, par0_ready, 1U), /* tx (ready)*/
  111. IO_FIELD(R_IRQ_MASK0_RD, par0_data, 1U), /* rx (data)*/
  112. IO_FIELD(R_IRQ_MASK0_RD, par0_ecp_cmd, 1U), /* ecp_cmd */
  113. IO_FIELD(R_IRQ_MASK0_RD, par0_peri, 1U), /* peri */
  114. 0
  115. },
  116. {
  117. R_PAR1_CTRL_DATA,
  118. R_PAR1_STATUS_DATA,
  119. R_PAR1_CONFIG,
  120. R_PAR1_DELAY,
  121. /* DMA interrupt stuff */
  122. 4,
  123. 1U << 8, /* uses DMA 4 and 5 */
  124. R_DMA_CH4_CLR_INTR,
  125. R_DMA_CH4_FIRST,
  126. R_DMA_CH4_CMD,
  127. R_DMA_CH5_CLR_INTR,
  128. R_DMA_CH5_FIRST,
  129. R_DMA_CH5_CMD,
  130. /* Non DMA interrupt stuff */
  131. IO_BITNR(R_VECT_MASK_RD, par1),
  132. R_IRQ_MASK1_RD,
  133. R_IRQ_MASK1_CLR,
  134. R_IRQ_READ1,
  135. R_IRQ_MASK1_SET,
  136. IO_FIELD(R_IRQ_MASK1_RD, par1_ready, 1U), /* tx (ready)*/
  137. IO_FIELD(R_IRQ_MASK1_RD, par1_data, 1U), /* rx (data)*/
  138. IO_FIELD(R_IRQ_MASK1_RD, par1_ecp_cmd, 1U), /* ecp_cmd */
  139. IO_FIELD(R_IRQ_MASK1_RD, par1_peri, 1U), /* peri */
  140. 1
  141. }
  142. };
  143. #define NR_PORTS (sizeof(port_table)/sizeof(struct etrax100par_struct))
  144. static void
  145. parport_etrax_write_data(struct parport *p, unsigned char value)
  146. {
  147. struct etrax100par_struct *info =
  148. (struct etrax100par_struct *)p->private_data;
  149. DPRINTK("* E100 PP %d: etrax_write_data %02Xn", p->portnum, value);
  150. SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, data, value);
  151. *info->reg_ctrl_data = info->reg_ctrl_data_shadow;
  152. }
  153. static unsigned char
  154. parport_etrax_read_data(struct parport *p)
  155. {
  156. unsigned char ret;
  157. struct etrax100par_struct *info =
  158. (struct etrax100par_struct *)p->private_data;
  159. ret = IO_EXTRACT(R_PAR0_STATUS_DATA, data, *info->reg_status_data);
  160. DPRINTK("* E100 PP %d: etrax_read_data %02Xn", p->portnum, ret);
  161. return ret;
  162. }
  163. static void
  164. parport_etrax_write_control(struct parport *p, unsigned char control)
  165. {
  166. struct etrax100par_struct *info =
  167. (struct etrax100par_struct *)p->private_data;
  168. DPRINTK("* E100 PP %d: etrax_write_control %02xn", p->portnum, control);
  169.   
  170. SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, strb,
  171.      (control & PARPORT_CONTROL_STROBE) > 0);
  172. SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, autofd,
  173.      (control & PARPORT_CONTROL_AUTOFD) > 0);
  174. SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, init,
  175.      (control & PARPORT_CONTROL_INIT) == 0);
  176. SETF(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, seli,
  177.      (control & PARPORT_CONTROL_SELECT) > 0);
  178. *info->reg_ctrl_data = info->reg_ctrl_data_shadow;
  179. }
  180. static unsigned char
  181. parport_etrax_read_control( struct parport *p)
  182. {
  183. unsigned char ret = 0;
  184. struct etrax100par_struct *info =
  185. (struct etrax100par_struct *)p->private_data;
  186. if (IO_EXTRACT(R_PAR0_CTRL_DATA, strb, info->reg_ctrl_data_shadow))
  187. ret |= PARPORT_CONTROL_STROBE;
  188. if (IO_EXTRACT(R_PAR0_CTRL_DATA, autofd, info->reg_ctrl_data_shadow))
  189. ret |= PARPORT_CONTROL_AUTOFD;
  190. if (!IO_EXTRACT(R_PAR0_CTRL_DATA, init, info->reg_ctrl_data_shadow))
  191. ret |= PARPORT_CONTROL_INIT;
  192. if (IO_EXTRACT(R_PAR0_CTRL_DATA, seli, info->reg_ctrl_data_shadow))
  193. ret |= PARPORT_CONTROL_SELECT;
  194. DPRINTK("* E100 PP %d: etrax_read_control %02xn", p->portnum, ret);
  195. return ret;
  196. }
  197. static unsigned char
  198. parport_etrax_frob_control(struct parport *p, unsigned char mask,
  199.                            unsigned char val)
  200. {
  201. unsigned char old;
  202. DPRINTK("* E100 PP %d: frob_control mask %02x, value %02xn",
  203. p->portnum, mask, val);
  204. old = parport_etrax_read_control(p);
  205. parport_etrax_write_control(p, (old & ~mask) ^ val);
  206. return old;
  207. }
  208. static unsigned char
  209. parport_etrax_read_status(struct parport *p)
  210. {
  211. unsigned char ret = 0;
  212. struct etrax100par_struct *info =
  213. (struct etrax100par_struct *)p->private_data;
  214. if (IO_EXTRACT(R_PAR0_STATUS_DATA, fault, *info->reg_status_data))
  215. ret |= PARPORT_STATUS_ERROR;
  216. if (IO_EXTRACT(R_PAR0_STATUS_DATA, sel, *info->reg_status_data))
  217. ret |= PARPORT_STATUS_SELECT;
  218. if (IO_EXTRACT(R_PAR0_STATUS_DATA, perr, *info->reg_status_data))
  219. ret |= PARPORT_STATUS_PAPEROUT;
  220. if (IO_EXTRACT(R_PAR0_STATUS_DATA, ack, *info->reg_status_data))
  221. ret |= PARPORT_STATUS_ACK;
  222. if (!IO_EXTRACT(R_PAR0_STATUS_DATA, busy, *info->reg_status_data))
  223. ret |= PARPORT_STATUS_BUSY;
  224. DPRINTK("* E100 PP %d: status register %04xn",
  225. p->portnum, *info->reg_status_data);
  226. DPRINTK("* E100 PP %d: read_status %02xn", p->portnum, ret);
  227. return ret;
  228. }
  229. static void
  230. parport_etrax_enable_irq(struct parport *p)
  231. {
  232. struct etrax100par_struct *info =
  233. (struct etrax100par_struct *)p->private_data;
  234. *info->irq_mask_set = info->irq_mask_tx;
  235. DPRINTK("* E100 PP %d: enable irqn", p->portnum);
  236. }
  237. static void
  238. parport_etrax_disable_irq(struct parport *p)
  239. {
  240. struct etrax100par_struct *info =
  241. (struct etrax100par_struct *)p->private_data;
  242. *info->irq_mask_clr = info->irq_mask_tx;
  243. DPRINTK("* E100 PP %d: disable irqn", p->portnum);
  244. }
  245. static void
  246. parport_etrax_data_forward(struct parport *p)
  247. {
  248. struct etrax100par_struct *info =
  249. (struct etrax100par_struct *)p->private_data;
  250. DPRINTK("* E100 PP %d: forward moden", p->portnum);
  251. SETS(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, oe, enable);
  252. *info->reg_ctrl_data = info->reg_ctrl_data_shadow;
  253. }
  254. static void
  255. parport_etrax_data_reverse(struct parport *p)
  256. {
  257. struct etrax100par_struct *info =
  258. (struct etrax100par_struct *)p->private_data;
  259. DPRINTK("* E100 PP %d: reverse moden", p->portnum);
  260. SETS(info->reg_ctrl_data_shadow, R_PAR0_CTRL_DATA, oe, disable);
  261. *info->reg_ctrl_data = info->reg_ctrl_data_shadow;
  262. }
  263. static void
  264. parport_etrax_init_state(struct pardevice *dev, struct parport_state *s)
  265. {
  266. DPRINTK("* E100 PP: parport_etrax_init_staten");
  267. }
  268. static void
  269. parport_etrax_save_state(struct parport *p, struct parport_state *s)
  270. {
  271. DPRINTK("* E100 PP: parport_etrax_save_staten");
  272. }
  273. static void
  274. parport_etrax_restore_state(struct parport *p, struct parport_state *s)
  275. {
  276. DPRINTK("* E100 PP: parport_etrax_restore_staten");
  277. }
  278. static void
  279. parport_etrax_inc_use_count(void)
  280. {
  281. MOD_INC_USE_COUNT;
  282. }
  283. static void
  284. parport_etrax_dec_use_count(void)
  285. {
  286. MOD_DEC_USE_COUNT;
  287. }
  288. static struct
  289. parport_operations pp_etrax_ops = {
  290. parport_etrax_write_data,
  291. parport_etrax_read_data,
  292. parport_etrax_write_control,
  293. parport_etrax_read_control,
  294. parport_etrax_frob_control,
  295. parport_etrax_read_status,
  296. parport_etrax_enable_irq,
  297. parport_etrax_disable_irq,
  298. parport_etrax_data_forward, 
  299. parport_etrax_data_reverse, 
  300. parport_etrax_init_state,
  301. parport_etrax_save_state,
  302. parport_etrax_restore_state,
  303. parport_etrax_inc_use_count,
  304. parport_etrax_dec_use_count,
  305. parport_ieee1284_epp_write_data,
  306. parport_ieee1284_epp_read_data,
  307. parport_ieee1284_epp_write_addr,
  308. parport_ieee1284_epp_read_addr,
  309. parport_ieee1284_ecp_write_data,
  310. parport_ieee1284_ecp_read_data,
  311. parport_ieee1284_ecp_write_addr,
  312. parport_ieee1284_write_compat,
  313. parport_ieee1284_read_nibble,
  314. parport_ieee1284_read_byte,
  315. };
  316. static void 
  317. parport_etrax_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  318. {
  319. struct etrax100par_struct *info = (struct etrax100par_struct *)
  320. ((struct parport *)dev_id)->private_data;
  321. DPRINTK("* E100 PP %d: Interrupt receivedn",
  322. ((struct parport *)dev_id)->portnum);
  323. *info->irq_mask_clr = info->irq_mask_tx;
  324. parport_generic_irq(irq, (struct parport *)dev_id, regs);
  325. }
  326. /* ----------- Initialisation code --------------------------------- */
  327. static void __init
  328. parport_etrax_show_parallel_version(void)
  329. {
  330. printk("ETRAX 100LX parallel port driver v1.0, (c) 2001 Axis Communications ABn");
  331. }
  332. #ifdef CONFIG_ETRAX_PAR0_DMA
  333. #define PAR0_USE_DMA 1
  334. #else
  335. #define PAR0_USE_DMA 0
  336. #endif
  337. #ifdef CONFIG_ETRAX_PAR1_DMA
  338. #define PAR1_USE_DMA 1
  339. #else
  340. #define PAR1_USE_DMA 0
  341. #endif
  342. static void __init
  343. parport_etrax_init_registers(void)
  344. {
  345. struct etrax100par_struct *info;
  346. int i;
  347. for (i = 0, info = port_table; i < 2; i++, info++) {
  348. #ifndef CONFIG_ETRAX_PARALLEL_PORT0
  349. if (i == 0)
  350. continue;
  351. #endif
  352. #ifndef CONFIG_ETRAX_PARALLEL_PORT1
  353. if (i == 1)
  354. continue;
  355. #endif
  356. info->reg_config_shadow = 
  357. IO_STATE(R_PAR0_CONFIG, iseli, inv)       |
  358. IO_STATE(R_PAR0_CONFIG, iautofd, inv)     |
  359. IO_STATE(R_PAR0_CONFIG, istrb, inv)       |
  360. IO_STATE(R_PAR0_CONFIG, iinit, inv)       |
  361. IO_STATE(R_PAR0_CONFIG, rle_in, disable)  |
  362. IO_STATE(R_PAR0_CONFIG, rle_out, disable) |
  363. IO_STATE(R_PAR0_CONFIG, enable, on)       |
  364. IO_STATE(R_PAR0_CONFIG, force, off)       |
  365. IO_STATE(R_PAR0_CONFIG, ign_ack, wait)    |
  366. IO_STATE(R_PAR0_CONFIG, oe_ack, wait_oe)  |
  367. IO_STATE(R_PAR0_CONFIG, mode, manual);
  368. if ((i == 0 && PAR0_USE_DMA) || (i == 1 && PAR1_USE_DMA))
  369. info->reg_config_shadow |=
  370. IO_STATE(R_PAR0_CONFIG, dma, enable);
  371. else
  372. info->reg_config_shadow |=
  373. IO_STATE(R_PAR0_CONFIG, dma, disable);
  374. *info->reg_config = info->reg_config_shadow;
  375. info->reg_ctrl_data_shadow = 
  376. IO_STATE(R_PAR0_CTRL_DATA, peri_int, nop)    |
  377. IO_STATE(R_PAR0_CTRL_DATA, oe, enable)       |
  378. IO_STATE(R_PAR0_CTRL_DATA, seli, inactive)   |
  379. IO_STATE(R_PAR0_CTRL_DATA, autofd, inactive) |
  380. IO_STATE(R_PAR0_CTRL_DATA, strb, inactive)   |
  381. IO_STATE(R_PAR0_CTRL_DATA, init, inactive)   |
  382. IO_STATE(R_PAR0_CTRL_DATA, ecp_cmd, data)    |
  383. IO_FIELD(R_PAR0_CTRL_DATA, data, 0);
  384. *info->reg_ctrl_data = info->reg_ctrl_data_shadow;
  385. /* Clear peri int without setting shadow */
  386. *info->reg_ctrl_data = info->reg_ctrl_data_shadow |
  387. IO_STATE(R_PAR0_CTRL_DATA, peri_int, ack);
  388. info->reg_delay_shadow = 
  389. IO_FIELD(R_PAR0_DELAY, setup, 5)  |
  390. IO_FIELD(R_PAR0_DELAY, strobe, 5) |
  391. IO_FIELD(R_PAR0_DELAY, hold, 5);
  392. *info->reg_delay = info->reg_delay_shadow;
  393. }
  394. #ifdef CONFIG_ETRAX_PARALLEL_PORT0
  395. #ifdef CONFIG_ETRAX_PAR0_DMA
  396. RESET_DMA(PAR0_TX_DMA_NBR);
  397. WAIT_DMA(PAR0_TX_DMA_NBR);
  398. #ifdef CONFIG_ETRAX_SERIAL_PORT2
  399. printk(" Warning - DMA clash with ser2!n");
  400. #endif /* SERIAL_PORT2 */
  401. #endif /* DMA */
  402. #endif /* PORT0 */
  403. #ifdef CONFIG_ETRAX_PARALLEL_PORT1
  404. #ifdef CONFIG_ETRAX_PAR1_DMA
  405. RESET_DMA(PAR1_TX_DMA_NBR);
  406. WAIT_DMA(PAR1_TX_DMA_NBR);
  407. #ifdef CONFIG_ETRAX_SERIAL_PORT3
  408. printk(" Warning - DMA clash with ser3!n");
  409. #endif /* SERIAL_PORT3 */
  410. #endif /* DMA */
  411. #endif /* PORT1 */
  412. int __init
  413. parport_etrax_init(void)
  414. {
  415. struct parport *p;
  416. int port_exists = 0;
  417. int i;
  418. struct etrax100par_struct *info;
  419.         const char *names[] = { "parallel 0 tx+rx", "parallel 1 tx+rx" };
  420. parport_etrax_show_parallel_version();
  421. parport_etrax_init_registers();
  422.         for (i = 0, info = port_table; i < NR_PORTS; i++, info++) {
  423. #ifndef CONFIG_ETRAX_PARALLEL_PORT0
  424. if (i == 0)
  425. continue;
  426. #endif
  427. #ifndef CONFIG_ETRAX_PARALLEL_PORT1
  428. if (i == 1)
  429. continue;
  430. #endif
  431.                 p = parport_register_port((unsigned long)0, info->int_irq,
  432.                                           PARPORT_DMA_NONE, &pp_etrax_ops);
  433.                 if (!p)
  434. continue;
  435.                 info->port = p;
  436.                 p->private_data = info;
  437.                 /* Axis FIXME: Set mode flags. */
  438.                 /* p->modes = PARPORT_MODE_TRISTATE | PARPORT_MODE_SAFEININT; */
  439.         if(request_irq(info->int_irq, parport_etrax_interrupt,
  440.                                SA_SHIRQ, names[i], p)) {
  441.          parport_unregister_port (p);
  442.                         continue;
  443.                 }
  444.                 printk(KERN_INFO "%s: ETRAX 100LX port %d using irqn",
  445.                        p->name, i);
  446.                 parport_proc_register(p);
  447.                 parport_announce_port(p);
  448.                 port_exists = 1;
  449.         }
  450. return port_exists;
  451. }
  452. void __exit
  453. parport_etrax_exit(void)
  454. {
  455. int i;
  456. struct etrax100par_struct *info;
  457.         for (i = 0, info = port_table; i < NR_PORTS; i++, info++) {
  458. #ifndef CONFIG_ETRAX_PARALLEL_PORT0
  459. if (i == 0)
  460. continue;
  461. #endif
  462. #ifndef CONFIG_ETRAX_PARALLEL_PORT1
  463. if (i == 1)
  464. continue;
  465. #endif
  466. if (info->int_irq != PARPORT_IRQ_NONE)
  467. free_irq(info->int_irq, info->port);
  468. parport_proc_unregister(info->port);
  469. parport_unregister_port(info->port);
  470.         }
  471. }