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