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