]> Git Repo - linux.git/blob - drivers/ata/pata_parport/epia.c
arm64: avoid prototype warnings for syscalls
[linux.git] / drivers / ata / pata_parport / epia.c
1 /* 
2         epia.c    (c) 1997-8  Grant R. Guenther <[email protected]>
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);
This page took 0.048526 seconds and 4 git commands to generate.