io.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * $Id: io.c,v 1.6 2004/03/16 00:07:50 lethal Exp $
  3. * Copyright (C) 2000 YAEGASHI Takeshi
  4. * Typical I/O routines for HD64461 system.
  5. */
  6. #include <linux/config.h>
  7. #include <asm/io.h>
  8. #include <asm/hd64461/hd64461.h>
  9. #define MEM_BASE (CONFIG_HD64461_IOBASE - HD64461_STBCR)
  10. static __inline__ unsigned long PORT2ADDR(unsigned long port)
  11. {
  12. /* 16550A: HD64461 internal */
  13. if (0x3f8<=port && port<=0x3ff)
  14. return CONFIG_HD64461_IOBASE + 0x8000 + ((port-0x3f8)<<1);
  15. if (0x2f8<=port && port<=0x2ff)
  16. return CONFIG_HD64461_IOBASE + 0x7000 + ((port-0x2f8)<<1);
  17. #ifdef CONFIG_HD64461_ENABLER
  18. /* NE2000: HD64461 PCMCIA channel 0 (I/O) */
  19. if (0x300<=port && port<=0x31f)
  20. return 0xba000000 + port;
  21. /* ide0: HD64461 PCMCIA channel 1 (memory) */
  22. /* On HP690, CF in slot 1 is configured as a memory card
  23. device. See CF+ and CompactFlash Specification for the
  24. detail of CF's memory mapped addressing. */
  25. if (0x1f0<=port && port<=0x1f7) return 0xb5000000 + port;
  26. if (port == 0x3f6) return 0xb50001fe;
  27. if (port == 0x3f7) return 0xb50001ff;
  28. /* ide1 */
  29. if (0x170<=port && port<=0x177) return 0xba000000 + port;
  30. if (port == 0x376) return 0xba000376;
  31. if (port == 0x377) return 0xba000377;
  32. #endif
  33. /* ??? */
  34. if (port < 0xf000) return 0xa0000000 + port;
  35. /* PCMCIA channel 0, I/O (0xba000000) */
  36. if (port < 0x10000) return 0xba000000 + port - 0xf000;
  37. /* HD64461 internal devices (0xb0000000) */
  38. if (port < 0x20000) return CONFIG_HD64461_IOBASE + port - 0x10000;
  39. /* PCMCIA channel 0, I/O (0xba000000) */
  40. if (port < 0x30000) return 0xba000000 + port - 0x20000;
  41. /* PCMCIA channel 1, memory (0xb5000000) */
  42. if (port < 0x40000) return 0xb5000000 + port - 0x30000;
  43. /* Whole physical address space (0xa0000000) */
  44. return 0xa0000000 + (port & 0x1fffffff);
  45. }
  46. static inline void delay(void)
  47. {
  48. ctrl_inw(0xa0000000);
  49. }
  50. unsigned char hd64461_inb(unsigned long port)
  51. {
  52. return *(volatile unsigned char*)PORT2ADDR(port);
  53. }
  54. unsigned char hd64461_inb_p(unsigned long port)
  55. {
  56. unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
  57. delay();
  58. return v;
  59. }
  60. unsigned short hd64461_inw(unsigned long port)
  61. {
  62. return *(volatile unsigned short*)PORT2ADDR(port);
  63. }
  64. unsigned int hd64461_inl(unsigned long port)
  65. {
  66. return *(volatile unsigned long*)PORT2ADDR(port);
  67. }
  68. void hd64461_outb(unsigned char b, unsigned long port)
  69. {
  70. *(volatile unsigned char*)PORT2ADDR(port) = b;
  71. }
  72. void hd64461_outb_p(unsigned char b, unsigned long port)
  73. {
  74. *(volatile unsigned char*)PORT2ADDR(port) = b;
  75. delay();
  76. }
  77. void hd64461_outw(unsigned short b, unsigned long port)
  78. {
  79. *(volatile unsigned short*)PORT2ADDR(port) = b;
  80. }
  81. void hd64461_outl(unsigned int b, unsigned long port)
  82. {
  83. *(volatile unsigned long*)PORT2ADDR(port) = b;
  84. }
  85. void hd64461_insb(unsigned long port, void *buffer, unsigned long count)
  86. {
  87. volatile unsigned char* addr=(volatile unsigned char*)PORT2ADDR(port);
  88. unsigned char *buf=buffer;
  89. while(count--) *buf++=*addr;
  90. }
  91. void hd64461_insw(unsigned long port, void *buffer, unsigned long count)
  92. {
  93. volatile unsigned short* addr=(volatile unsigned short*)PORT2ADDR(port);
  94. unsigned short *buf=buffer;
  95. while(count--) *buf++=*addr;
  96. }
  97. void hd64461_insl(unsigned long port, void *buffer, unsigned long count)
  98. {
  99. volatile unsigned long* addr=(volatile unsigned long*)PORT2ADDR(port);
  100. unsigned long *buf=buffer;
  101. while(count--) *buf++=*addr;
  102. }
  103. void hd64461_outsb(unsigned long port, const void *buffer, unsigned long count)
  104. {
  105. volatile unsigned char* addr=(volatile unsigned char*)PORT2ADDR(port);
  106. const unsigned char *buf=buffer;
  107. while(count--) *addr=*buf++;
  108. }
  109. void hd64461_outsw(unsigned long port, const void *buffer, unsigned long count)
  110. {
  111. volatile unsigned short* addr=(volatile unsigned short*)PORT2ADDR(port);
  112. const unsigned short *buf=buffer;
  113. while(count--) *addr=*buf++;
  114. }
  115. void hd64461_outsl(unsigned long port, const void *buffer, unsigned long count)
  116. {
  117. volatile unsigned long* addr=(volatile unsigned long*)PORT2ADDR(port);
  118. const unsigned long *buf=buffer;
  119. while(count--) *addr=*buf++;
  120. }
  121. unsigned short hd64461_readw(unsigned long addr)
  122. {
  123. return *(volatile unsigned short*)(MEM_BASE+addr);
  124. }
  125. void hd64461_writew(unsigned short b, unsigned long addr)
  126. {
  127. *(volatile unsigned short*)(MEM_BASE+addr) = b;
  128. }