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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: parport.h,v 1.11 2001/05/11 07:54:24 davem Exp $
  2.  * parport.h: sparc64 specific parport initialization and dma.
  3.  *
  4.  * Copyright (C) 1999  Eddie C. Dost  (ecd@skynet.be)
  5.  */
  6. #ifndef _ASM_SPARC64_PARPORT_H
  7. #define _ASM_SPARC64_PARPORT_H 1
  8. #include <asm/ebus.h>
  9. #include <asm/isa.h>
  10. #include <asm/ns87303.h>
  11. #define PARPORT_PC_MAX_PORTS PARPORT_MAX
  12. static struct linux_ebus_dma *sparc_ebus_dmas[PARPORT_PC_MAX_PORTS];
  13. static __inline__ void
  14. reset_dma(unsigned int dmanr)
  15. {
  16. unsigned int dcsr;
  17. writel(EBUS_DCSR_RESET, &sparc_ebus_dmas[dmanr]->dcsr);
  18. udelay(1);
  19. dcsr = EBUS_DCSR_BURST_SZ_16 | EBUS_DCSR_TCI_DIS |
  20.        EBUS_DCSR_EN_CNT | EBUS_DCSR_INT_EN;
  21. writel(dcsr, &sparc_ebus_dmas[dmanr]->dcsr);
  22. }
  23. static __inline__ void
  24. enable_dma(unsigned int dmanr)
  25. {
  26. unsigned int dcsr;
  27. dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
  28. dcsr |= EBUS_DCSR_EN_DMA;
  29. writel(dcsr, &sparc_ebus_dmas[dmanr]->dcsr);
  30. }
  31. static __inline__ void
  32. disable_dma(unsigned int dmanr)
  33. {
  34. unsigned int dcsr;
  35. dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
  36. if (dcsr & EBUS_DCSR_EN_DMA) {
  37. while (dcsr & EBUS_DCSR_DRAIN) {
  38. udelay(1);
  39. dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
  40. }
  41. dcsr &= ~(EBUS_DCSR_EN_DMA);
  42. writel(dcsr, &sparc_ebus_dmas[dmanr]->dcsr);
  43. dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
  44. if (dcsr & EBUS_DCSR_ERR_PEND)
  45. reset_dma(dmanr);
  46. }
  47. }
  48. static __inline__ void
  49. clear_dma_ff(unsigned int dmanr)
  50. {
  51. /* nothing */
  52. }
  53. static __inline__ void
  54. set_dma_mode(unsigned int dmanr, char mode)
  55. {
  56. unsigned int dcsr;
  57. dcsr = readl(&sparc_ebus_dmas[dmanr]->dcsr);
  58. dcsr |= EBUS_DCSR_EN_CNT | EBUS_DCSR_TC;
  59. if (mode == DMA_MODE_WRITE)
  60. dcsr &= ~(EBUS_DCSR_WRITE);
  61. else
  62. dcsr |= EBUS_DCSR_WRITE;
  63. writel(dcsr, &sparc_ebus_dmas[dmanr]->dcsr);
  64. }
  65. static __inline__ void
  66. set_dma_addr(unsigned int dmanr, unsigned int addr)
  67. {
  68. writel(addr, &sparc_ebus_dmas[dmanr]->dacr);
  69. }
  70. static __inline__ void
  71. set_dma_count(unsigned int dmanr, unsigned int count)
  72. {
  73. writel(count, &sparc_ebus_dmas[dmanr]->dbcr);
  74. }
  75. static __inline__ int
  76. get_dma_residue(unsigned int dmanr)
  77. {
  78. int res;
  79. res = readl(&sparc_ebus_dmas[dmanr]->dbcr);
  80. if (res != 0)
  81. reset_dma(dmanr);
  82. return res;
  83. }
  84. static int ebus_ecpp_p(struct linux_ebus_device *edev)
  85. {
  86. if (!strcmp(edev->prom_name, "ecpp"))
  87. return 1;
  88. if (!strcmp(edev->prom_name, "parallel")) {
  89. char compat[19];
  90. prom_getstring(edev->prom_node,
  91.        "compatible",
  92.        compat, sizeof(compat));
  93. compat[18] = '';
  94. if (!strcmp(compat, "ecpp"))
  95. return 1;
  96. if (!strcmp(compat, "ns87317-ecpp") &&
  97.     !strcmp(compat + 13, "ecpp"))
  98. return 1;
  99. }
  100. return 0;
  101. }
  102. static int parport_isa_probe(int count)
  103. {
  104. struct isa_bridge *isa_br;
  105. struct isa_device *isa_dev;
  106. for_each_isa(isa_br) {
  107. for_each_isadev(isa_dev, isa_br) {
  108. struct isa_device *child;
  109. unsigned long base;
  110. if (strcmp(isa_dev->prom_name, "dma"))
  111. continue;
  112. child = isa_dev->child;
  113. while (child) {
  114. if (!strcmp(child->prom_name, "parallel"))
  115. break;
  116. child = child->next;
  117. }
  118. if (!child)
  119. continue;
  120. base = child->resource.start;
  121. /* No DMA, see commentary in
  122.  * asm-sparc64/floppy.h:isa_floppy_init()
  123.  */
  124. if (parport_pc_probe_port(base, base + 0x400,
  125.   child->irq, PARPORT_DMA_NOFIFO,
  126.   child->bus->self))
  127. count++;
  128. }
  129. }
  130. return count;
  131. }
  132. static int parport_pc_find_nonpci_ports (int autoirq, int autodma)
  133. {
  134. struct linux_ebus *ebus;
  135. struct linux_ebus_device *edev;
  136. int count = 0;
  137. if (!pci_present())
  138. return 0;
  139. for_each_ebus(ebus) {
  140. for_each_ebusdev(edev, ebus) {
  141. if (ebus_ecpp_p(edev)) {
  142. unsigned long base = edev->resource[0].start;
  143. unsigned long config = edev->resource[1].start;
  144. sparc_ebus_dmas[count] =
  145. (struct linux_ebus_dma *)
  146. edev->resource[2].start;
  147. reset_dma(count);
  148. /* Configure IRQ to Push Pull, Level Low */
  149. /* Enable ECP, set bit 2 of the CTR first */
  150. outb(0x04, base + 0x02);
  151. ns87303_modify(config, PCR,
  152.        PCR_EPP_ENABLE |
  153.        PCR_IRQ_ODRAIN,
  154.        PCR_ECP_ENABLE |
  155.        PCR_ECP_CLK_ENA |
  156.        PCR_IRQ_POLAR);
  157. /* CTR bit 5 controls direction of port */
  158. ns87303_modify(config, PTR,
  159.        0, PTR_LPT_REG_DIR);
  160. if (parport_pc_probe_port(base, base + 0x400,
  161.   edev->irqs[0],
  162.   count, ebus->self))
  163. count++;
  164. }
  165. }
  166. }
  167. count = parport_isa_probe(count);
  168. return count;
  169. }
  170. #endif /* !(_ASM_SPARC64_PARPORT_H */