File: /usr/src/linux/arch/sh/kernel/io_cat68701.c
1 /*
2 * linux/arch/sh/kernel/io_cat68701.c
3 *
4 * Copyright (C) 2000 Niibe Yutaka
5 * 2001 Yutaro Ebihara
6 *
7 * I/O routine and setup routines for A-ONE Corp CAT-68701 SH7708 Board
8 *
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file "COPYING" in the main directory of this archive
11 * for more details.
12 *
13 */
14
15 #include <asm/io.h>
16 #include <asm/machvec.h>
17 #include <linux/config.h>
18 #include <linux/module.h>
19
20 #define SH3_PCMCIA_BUG_WORKAROUND 1
21 #define DUMMY_READ_AREA6 0xba000000
22
23 #define PORT2ADDR(x) (cat68701_isa_port2addr(x))
24
25 static inline void delay(void)
26 {
27 ctrl_inw(0xa0000000);
28 }
29
30 unsigned char cat68701_inb(unsigned long port)
31 {
32 return *(volatile unsigned char*)PORT2ADDR(port);
33 }
34
35 unsigned short cat68701_inw(unsigned long port)
36 {
37 return *(volatile unsigned short*)PORT2ADDR(port);
38 }
39
40 unsigned int cat68701_inl(unsigned long port)
41 {
42 return *(volatile unsigned long*)PORT2ADDR(port);
43 }
44
45 unsigned char cat68701_inb_p(unsigned long port)
46 {
47 unsigned long v = *(volatile unsigned char*)PORT2ADDR(port);
48
49 delay();
50 return v;
51 }
52
53 unsigned short cat68701_inw_p(unsigned long port)
54 {
55 unsigned long v = *(volatile unsigned short*)PORT2ADDR(port);
56
57 delay();
58 return v;
59 }
60
61 unsigned int cat68701_inl_p(unsigned long port)
62 {
63 unsigned long v = *(volatile unsigned long*)PORT2ADDR(port);
64
65 delay();
66 return v;
67 }
68
69 void cat68701_insb(unsigned long port, void *buffer, unsigned long count)
70 {
71 unsigned char *buf=buffer;
72 while(count--) *buf++=inb(port);
73 }
74
75 void cat68701_insw(unsigned long port, void *buffer, unsigned long count)
76 {
77 unsigned short *buf=buffer;
78 while(count--) *buf++=inw(port);
79 #ifdef SH3_PCMCIA_BUG_WORKAROUND
80 ctrl_inb (DUMMY_READ_AREA6);
81 #endif
82 }
83
84 void cat68701_insl(unsigned long port, void *buffer, unsigned long count)
85 {
86 unsigned long *buf=buffer;
87 while(count--) *buf++=inl(port);
88 #ifdef SH3_PCMCIA_BUG_WORKAROUND
89 ctrl_inb (DUMMY_READ_AREA6);
90 #endif
91 }
92
93 void cat68701_outb(unsigned char b, unsigned long port)
94 {
95 *(volatile unsigned char*)PORT2ADDR(port) = b;
96 }
97
98 void cat68701_outw(unsigned short b, unsigned long port)
99 {
100 *(volatile unsigned short*)PORT2ADDR(port) = b;
101 }
102
103 void cat68701_outl(unsigned int b, unsigned long port)
104 {
105 *(volatile unsigned long*)PORT2ADDR(port) = b;
106 }
107
108 void cat68701_outb_p(unsigned char b, unsigned long port)
109 {
110 *(volatile unsigned char*)PORT2ADDR(port) = b;
111 delay();
112 }
113
114 void cat68701_outw_p(unsigned short b, unsigned long port)
115 {
116 *(volatile unsigned short*)PORT2ADDR(port) = b;
117 delay();
118 }
119
120 void cat68701_outl_p(unsigned int b, unsigned long port)
121 {
122 *(volatile unsigned long*)PORT2ADDR(port) = b;
123 delay();
124 }
125
126 void cat68701_outsb(unsigned long port, const void *buffer, unsigned long count)
127 {
128 const unsigned char *buf=buffer;
129 while(count--) outb(*buf++, port);
130 }
131
132 void cat68701_outsw(unsigned long port, const void *buffer, unsigned long count)
133 {
134 const unsigned short *buf=buffer;
135 while(count--) outw(*buf++, port);
136 #ifdef SH3_PCMCIA_BUG_WORKAROUND
137 ctrl_inb (DUMMY_READ_AREA6);
138 #endif
139 }
140
141 void cat68701_outsl(unsigned long port, const void *buffer, unsigned long count)
142 {
143 const unsigned long *buf=buffer;
144 while(count--) outl(*buf++, port);
145 #ifdef SH3_PCMCIA_BUG_WORKAROUND
146 ctrl_inb (DUMMY_READ_AREA6);
147 #endif
148 }
149
150 unsigned char cat68701_readb(unsigned long addr)
151 {
152 return *(volatile unsigned char*)addr;
153 }
154
155 unsigned short cat68701_readw(unsigned long addr)
156 {
157 return *(volatile unsigned short*)addr;
158 }
159
160 unsigned int cat68701_readl(unsigned long addr)
161 {
162 return *(volatile unsigned long*)addr;
163 }
164
165 void cat68701_writeb(unsigned char b, unsigned long addr)
166 {
167 *(volatile unsigned char*)addr = b;
168 }
169
170 void cat68701_writew(unsigned short b, unsigned long addr)
171 {
172 *(volatile unsigned short*)addr = b;
173 }
174
175 void cat68701_writel(unsigned int b, unsigned long addr)
176 {
177 *(volatile unsigned long*)addr = b;
178 }
179
180 void * cat68701_ioremap(unsigned long offset, unsigned long size)
181 {
182 return (void *) P2SEGADDR(offset);
183 }
184 EXPORT_SYMBOL(cat68701_ioremap);
185
186 void cat68701_iounmap(void *addr)
187 {
188 }
189 EXPORT_SYMBOL(cat68701_iounmap);
190
191 unsigned long cat68701_isa_port2addr(unsigned long offset)
192 {
193 /* CompactFlash (IDE) */
194 if(((offset >= 0x1f0) && (offset <= 0x1f7)) || (offset==0x3f6))
195 return 0xba000000 + offset;
196
197 /* INPUT PORT */
198 if((offset >= 0x3fc) && (offset <= 0x3fd))
199 return 0xb4007000 + offset;
200
201 /* OUTPUT PORT */
202 if((offset >= 0x3fe) && (offset <= 0x3ff))
203 return 0xb4007400 + offset;
204
205 return offset + 0xb4000000; /* other I/O (EREA 5)*/
206 }
207
208
209 int cat68701_irq_demux(int irq)
210 {
211 if(irq==13) return 14;
212 if(irq==7) return 10;
213 return irq;
214 }
215
216
217
218 /*-------------------------------------------------------*/
219
220 void setup_cat68701(){
221 /* dummy read erea5 (CS8900A) */
222 }
223
224 void init_cat68701_IRQ(){
225 make_imask_irq(10);
226 make_imask_irq(14);
227 }
228
229 #ifdef CONFIG_HEARTBEAT
230 #include <linux/sched.h>
231 void heartbeat_cat68701()
232 {
233 static unsigned int cnt = 0, period = 0 , bit = 0;
234 cnt += 1;
235 if (cnt < period) {
236 return;
237 }
238 cnt = 0;
239
240 /* Go through the points (roughly!):
241 * f(0)=10, f(1)=16, f(2)=20, f(5)=35,f(inf)->110
242 */
243 period = 110 - ( (300<<FSHIFT)/
244 ((avenrun[0]/5) + (3<<FSHIFT)) );
245
246 if(bit){ bit=0; }else{ bit=1; }
247 outw(bit<<15,0x3fe);
248 }
249 #endif /* CONFIG_HEARTBEAT */
250