more changes on original files
[linux-2.4.git] / drivers / block / paride / comm.c
1 /* 
2         comm.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
3                               Under the terms of the GNU General Public License.
4
5         comm.c is a low-level protocol driver for some older models
6         of the DataStor "Commuter" parallel to IDE adapter.  Some of
7         the parallel port devices marketed by Arista currently
8         use this adapter.
9 */
10
11 /* Changes:
12
13         1.01    GRG 1998.05.05  init_proto, release_proto
14
15 */
16
17 #define COMM_VERSION      "1.01"
18
19 #include <linux/module.h>
20 #include <linux/delay.h>
21 #include <linux/kernel.h>
22 #include <linux/types.h>
23 #include <linux/wait.h>
24 #include <asm/io.h>
25
26 #include "paride.h"
27
28 /* mode codes:  0  nybble reads, 8-bit writes
29                 1  8-bit reads and writes
30                 2  8-bit EPP mode
31 */
32
33 #define j44(a,b)        (((a>>3)&0x0f)|((b<<1)&0xf0))
34
35 #define P1      w2(5);w2(0xd);w2(0xd);w2(5);w2(4);
36 #define P2      w2(5);w2(7);w2(7);w2(5);w2(4);
37
38 /* cont = 0 - access the IDE register file 
39    cont = 1 - access the IDE command set 
40 */
41
42 static int  cont_map[2] = { 0x08, 0x10 };
43
44 static int comm_read_regr( PIA *pi, int cont, int regr )
45
46 {       int     l, h, r;
47
48         r = regr + cont_map[cont];
49
50         switch (pi->mode)  {
51
52         case 0: w0(r); P1; w0(0);
53                 w2(6); l = r1(); w0(0x80); h = r1(); w2(4);
54                 return j44(l,h);
55
56         case 1: w0(r+0x20); P1; 
57                 w0(0); w2(0x26); h = r0(); w2(4);
58                 return h;
59
60         case 2:
61         case 3:
62         case 4: w3(r+0x20); r1(); 
63                 w2(0x24); h = r4(); w2(4);
64                 return h;
65
66         }
67         return -1;
68 }       
69
70 static void comm_write_regr( PIA *pi, int cont, int regr, int val )
71
72 {       int  r;
73
74         r = regr + cont_map[cont];
75
76         switch (pi->mode)  {
77
78         case 0:
79         case 1: w0(r); P1; w0(val); P2;
80                 break;
81
82         case 2:
83         case 3:
84         case 4: w3(r); r1(); w4(val); 
85                 break;
86         }
87 }
88
89 static void comm_connect ( PIA *pi  )
90
91 {       pi->saved_r0 = r0();
92         pi->saved_r2 = r2();
93         w2(4); w0(0xff); w2(6);
94         w2(4); w0(0xaa); w2(6);
95         w2(4); w0(0x00); w2(6);
96         w2(4); w0(0x87); w2(6);
97         w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);
98 }
99
100 static void comm_disconnect ( PIA *pi )
101
102 {       w2(0); w2(0); w2(0); w2(4); 
103         w0(pi->saved_r0);
104         w2(pi->saved_r2);
105
106
107 static void comm_read_block( PIA *pi, char * buf, int count )
108
109 {       int     i, l, h;
110
111         switch (pi->mode) {
112         
113         case 0: w0(0x48); P1;
114                 for(i=0;i<count;i++) {
115                         w0(0); w2(6); l = r1();
116                         w0(0x80); h = r1(); w2(4);
117                         buf[i] = j44(l,h);
118                 }
119                 break;
120
121         case 1: w0(0x68); P1; w0(0);
122                 for(i=0;i<count;i++) {
123                         w2(0x26); buf[i] = r0(); w2(0x24);
124                 }
125                 w2(4);
126                 break;
127                 
128         case 2: w3(0x68); r1(); w2(0x24);
129                 for (i=0;i<count;i++) buf[i] = r4();
130                 w2(4);
131                 break;
132
133         case 3: w3(0x68); r1(); w2(0x24);
134                 for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
135                 w2(4);
136                 break;
137
138         case 4: w3(0x68); r1(); w2(0x24);
139                 for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
140                 w2(4);
141                 break;
142                 
143         }
144 }
145
146 /* NB: Watch out for the byte swapped writes ! */
147
148 static void comm_write_block( PIA *pi, char * buf, int count )
149
150 {       int     k;
151
152         switch (pi->mode) {
153
154         case 0:
155         case 1: w0(0x68); P1;
156                 for (k=0;k<count;k++) {
157                         w2(5); w0(buf[k^1]); w2(7);
158                 }
159                 w2(5); w2(4);
160                 break;
161
162         case 2: w3(0x48); r1();
163                 for (k=0;k<count;k++) w4(buf[k^1]);
164                 break;
165
166         case 3: w3(0x48); r1();
167                 for (k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
168                 break;
169
170         case 4: w3(0x48); r1();
171                 for (k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
172                 break;
173
174
175         }
176 }
177
178 static void comm_log_adapter( PIA *pi, char * scratch, int verbose )
179
180 {       char    *mode_string[5] = {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
181
182         printk("%s: comm %s, DataStor Commuter at 0x%x, ",
183                 pi->device,COMM_VERSION,pi->port);
184         printk("mode %d (%s), delay %d\n",pi->mode,
185                 mode_string[pi->mode],pi->delay);
186
187 }
188
189 static void comm_init_proto(PIA *pi)
190
191 {       MOD_INC_USE_COUNT;
192 }
193
194 static void comm_release_proto(PIA *pi)
195
196 {       MOD_DEC_USE_COUNT;
197 }
198
199 struct pi_protocol comm = {"comm",0,5,2,1,1,
200                            comm_write_regr,
201                            comm_read_regr,
202                            comm_write_block,
203                            comm_read_block,
204                            comm_connect,
205                            comm_disconnect,
206                            0,
207                            0,
208                            0,
209                            comm_log_adapter,
210                            comm_init_proto,
211                            comm_release_proto
212                           };
213
214
215 #ifdef MODULE
216
217 int     init_module(void)
218
219 {       return pi_register( &comm ) - 1;
220 }
221
222 void    cleanup_module(void)
223
224 {       pi_unregister( &comm );
225 }
226
227 #endif
228
229 /* end of comm.c */
230 MODULE_LICENSE("GPL");