xref: /openbmc/linux/drivers/ata/pata_parport/epia.c (revision 01985290)
1 /*
2         epia.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
3                               Under the terms of the GNU General Public License.
4 
5         epia.c is a low-level protocol driver for Shuttle Technologies
6 	EPIA parallel to IDE adapter chip.  This device is now obsolete
7 	and has been replaced with the EPAT chip, which is supported
8 	by epat.c, however, some devices based on EPIA are still
9 	available.
10 
11 */
12 
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/delay.h>
16 #include <linux/kernel.h>
17 #include <linux/types.h>
18 #include <linux/wait.h>
19 #include <asm/io.h>
20 
21 #include <linux/pata_parport.h>
22 
23 /* mode codes:  0  nybble reads on port 1, 8-bit writes
24                 1  5/3 reads on ports 1 & 2, 8-bit writes
25                 2  8-bit reads and writes
26                 3  8-bit EPP mode
27 		4  16-bit EPP
28 		5  32-bit EPP
29 */
30 
31 #define j44(a,b)                (((a>>4)&0x0f)+(b&0xf0))
32 #define j53(a,b)                (((a>>3)&0x1f)+((b<<4)&0xe0))
33 
34 /* cont =  0   IDE register file
35    cont =  1   IDE control registers
36 */
37 
38 static int cont_map[2] = { 0, 0x80 };
39 
40 static int epia_read_regr(struct pi_adapter *pi, int cont, int regr)
41 
42 {       int     a, b, r;
43 
44 	regr += cont_map[cont];
45 
46         switch (pi->mode)  {
47 
48         case 0: r = regr^0x39;
49                 w0(r); w2(1); w2(3); w0(r);
50                 a = r1(); w2(1); b = r1(); w2(4);
51                 return j44(a,b);
52 
53         case 1: r = regr^0x31;
54                 w0(r); w2(1); w0(r&0x37);
55                 w2(3); w2(5); w0(r|0xf0);
56                 a = r1(); b = r2(); w2(4);
57                 return j53(a,b);
58 
59         case 2: r = regr^0x29;
60                 w0(r); w2(1); w2(0X21); w2(0x23);
61                 a = r0(); w2(4);
62                 return a;
63 
64 	case 3:
65 	case 4:
66         case 5: w3(regr); w2(0x24); a = r4(); w2(4);
67                 return a;
68 
69         }
70         return -1;
71 }
72 
73 static void epia_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
74 
75 {       int  r;
76 
77 	regr += cont_map[cont];
78 
79         switch (pi->mode)  {
80 
81         case 0:
82         case 1:
83         case 2: r = regr^0x19;
84                 w0(r); w2(1); w0(val); w2(3); w2(4);
85                 break;
86 
87 	case 3:
88 	case 4:
89         case 5: r = regr^0x40;
90                 w3(r); w4(val); w2(4);
91                 break;
92         }
93 }
94 
95 #define WR(r,v)         epia_write_regr(pi,0,r,v)
96 #define RR(r)           (epia_read_regr(pi,0,r))
97 
98 /* The use of register 0x84 is entirely unclear - it seems to control
99    some EPP counters ...  currently we know about 3 different block
100    sizes:  the standard 512 byte reads and writes, 12 byte writes and
101    2048 byte reads (the last two being used in the CDrom drivers.
102 */
103 
104 static void epia_connect(struct pi_adapter *pi)
105 
106 {       pi->saved_r0 = r0();
107         pi->saved_r2 = r2();
108 
109         w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);
110         w2(1); w2(4);
111         if (pi->mode >= 3) {
112                 w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);
113                 w2(0x24); w2(0x26); w2(4);
114         }
115         WR(0x86,8);
116 }
117 
118 static void epia_disconnect(struct pi_adapter *pi)
119 
120 {       /* WR(0x84,0x10); */
121         w0(pi->saved_r0);
122         w2(1); w2(4);
123         w0(pi->saved_r0);
124         w2(pi->saved_r2);
125 }
126 
127 static void epia_read_block(struct pi_adapter *pi, char *buf, int count)
128 
129 {       int     k, ph, a, b;
130 
131         switch (pi->mode) {
132 
133         case 0: w0(0x81); w2(1); w2(3); w0(0xc1);
134                 ph = 1;
135                 for (k=0;k<count;k++) {
136                         w2(2+ph); a = r1();
137                         w2(4+ph); b = r1();
138                         buf[k] = j44(a,b);
139                         ph = 1 - ph;
140                 }
141                 w0(0); w2(4);
142                 break;
143 
144         case 1: w0(0x91); w2(1); w0(0x10); w2(3);
145                 w0(0x51); w2(5); w0(0xd1);
146                 ph = 1;
147                 for (k=0;k<count;k++) {
148                         w2(4+ph);
149                         a = r1(); b = r2();
150                         buf[k] = j53(a,b);
151                         ph = 1 - ph;
152                 }
153                 w0(0); w2(4);
154                 break;
155 
156         case 2: w0(0x89); w2(1); w2(0x23); w2(0x21);
157                 ph = 1;
158                 for (k=0;k<count;k++) {
159                         w2(0x24+ph);
160                         buf[k] = r0();
161                         ph = 1 - ph;
162                 }
163                 w2(6); w2(4);
164                 break;
165 
166         case 3: if (count > 512) WR(0x84,3);
167 		w3(0); w2(0x24);
168                 for (k=0;k<count;k++) buf[k] = r4();
169                 w2(4); WR(0x84,0);
170                 break;
171 
172         case 4: if (count > 512) WR(0x84,3);
173 		w3(0); w2(0x24);
174 		for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
175                 w2(4); WR(0x84,0);
176                 break;
177 
178         case 5: if (count > 512) WR(0x84,3);
179 		w3(0); w2(0x24);
180                 for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
181                 w2(4); WR(0x84,0);
182                 break;
183 
184         }
185 }
186 
187 static void epia_write_block(struct pi_adapter *pi, char *buf, int count)
188 
189 {       int     ph, k, last, d;
190 
191         switch (pi->mode) {
192 
193         case 0:
194         case 1:
195         case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5);
196                 ph = 0;  last = 0x8000;
197                 for (k=0;k<count;k++) {
198                         d = buf[k];
199                         if (d != last) { last = d; w0(d); }
200                         w2(4+ph);
201                         ph = 1 - ph;
202                 }
203                 w2(7); w2(4);
204                 break;
205 
206         case 3: if (count < 512) WR(0x84,1);
207 		w3(0x40);
208                 for (k=0;k<count;k++) w4(buf[k]);
209 		if (count < 512) WR(0x84,0);
210                 break;
211 
212         case 4: if (count < 512) WR(0x84,1);
213 		w3(0x40);
214                 for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
215 		if (count < 512) WR(0x84,0);
216                 break;
217 
218         case 5: if (count < 512) WR(0x84,1);
219 		w3(0x40);
220                 for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
221 		if (count < 512) WR(0x84,0);
222                 break;
223 
224         }
225 
226 }
227 
228 static int epia_test_proto(struct pi_adapter *pi)
229 
230 {       int     j, k, f;
231 	int	e[2] = {0,0};
232 	char scratch[512];
233 
234         epia_connect(pi);
235         for (j=0;j<2;j++) {
236             WR(6,0xa0+j*0x10);
237             for (k=0;k<256;k++) {
238                 WR(2,k^0xaa);
239                 WR(3,k^0x55);
240                 if (RR(2) != (k^0xaa)) e[j]++;
241                 }
242 	    WR(2,1); WR(3,1);
243             }
244         epia_disconnect(pi);
245 
246         f = 0;
247         epia_connect(pi);
248         WR(0x84,8);
249         epia_read_block(pi,scratch,512);
250         for (k=0;k<256;k++) {
251             if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++;
252             if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++;
253         }
254         WR(0x84,0);
255         epia_disconnect(pi);
256 
257 	dev_dbg(&pi->dev, "epia: port 0x%x, mode %d, test=(%d,%d,%d)\n",
258 	       pi->port, pi->mode, e[0], e[1], f);
259 
260         return (e[0] && e[1]) || f;
261 
262 }
263 
264 
265 static void epia_log_adapter(struct pi_adapter *pi)
266 
267 {       char    *mode_string[6] = {"4-bit","5/3","8-bit",
268 				   "EPP-8","EPP-16","EPP-32"};
269 
270 	dev_info(&pi->dev, "Shuttle EPIA at 0x%x, mode %d (%s), delay %d\n",
271 		pi->port, pi->mode, mode_string[pi->mode], pi->delay);
272 }
273 
274 static struct pi_protocol epia = {
275 	.owner		= THIS_MODULE,
276 	.name		= "epia",
277 	.max_mode	= 6,
278 	.epp_first	= 3,
279 	.default_delay	= 1,
280 	.max_units	= 1,
281 	.write_regr	= epia_write_regr,
282 	.read_regr	= epia_read_regr,
283 	.write_block	= epia_write_block,
284 	.read_block	= epia_read_block,
285 	.connect	= epia_connect,
286 	.disconnect	= epia_disconnect,
287 	.test_proto	= epia_test_proto,
288 	.log_adapter	= epia_log_adapter,
289 };
290 
291 MODULE_LICENSE("GPL");
292 module_pata_parport_driver(epia);
293