xref: /openbmc/linux/drivers/ata/pata_parport/dstr.c (revision f4356947)
1 /*
2         dstr.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
3                               Under the terms of the GNU General Public License.
4 
5         dstr.c is a low-level protocol driver for the
6         DataStor EP2000 parallel to IDE adapter chip.
7 
8 */
9 
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/delay.h>
13 #include <linux/kernel.h>
14 #include <linux/types.h>
15 #include <linux/wait.h>
16 #include <asm/io.h>
17 #include "pata_parport.h"
18 
19 /* mode codes:  0  nybble reads, 8-bit writes
20                 1  8-bit reads and writes
21                 2  8-bit EPP mode
22 		3  EPP-16
23 		4  EPP-32
24 */
25 
26 #define j44(a,b)  (((a>>3)&0x07)|((~a>>4)&0x08)|((b<<1)&0x70)|((~b)&0x80))
27 
28 #define P1	w2(5);w2(0xd);w2(5);w2(4);
29 #define P2	w2(5);w2(7);w2(5);w2(4);
30 #define P3      w2(6);w2(4);w2(6);w2(4);
31 
32 /* cont = 0 - access the IDE register file
33    cont = 1 - access the IDE command set
34 */
35 
36 static int  cont_map[2] = { 0x20, 0x40 };
37 
38 static int dstr_read_regr(struct pi_adapter *pi, int cont, int regr)
39 
40 {       int     a, b, r;
41 
42         r = regr + cont_map[cont];
43 
44 	w0(0x81); P1;
45 	if (pi->mode) { w0(0x11); } else { w0(1); }
46 	P2; w0(r); P1;
47 
48         switch (pi->mode)  {
49 
50         case 0: w2(6); a = r1(); w2(4); w2(6); b = r1(); w2(4);
51                 return j44(a,b);
52 
53         case 1: w0(0); w2(0x26); a = r0(); w2(4);
54                 return a;
55 
56 	case 2:
57 	case 3:
58         case 4: w2(0x24); a = r4(); w2(4);
59                 return a;
60 
61         }
62         return -1;
63 }
64 
65 static void dstr_write_regr(struct pi_adapter *pi, int cont, int regr, int val)
66 
67 {       int  r;
68 
69         r = regr + cont_map[cont];
70 
71 	w0(0x81); P1;
72 	if (pi->mode >= 2) { w0(0x11); } else { w0(1); }
73 	P2; w0(r); P1;
74 
75         switch (pi->mode)  {
76 
77         case 0:
78         case 1: w0(val); w2(5); w2(7); w2(5); w2(4);
79 		break;
80 
81 	case 2:
82 	case 3:
83         case 4: w4(val);
84                 break;
85         }
86 }
87 
88 #define  CCP(x)  w0(0xff);w2(0xc);w2(4);\
89 		 w0(0xaa);w0(0x55);w0(0);w0(0xff);w0(0x87);w0(0x78);\
90 		 w0(x);w2(5);w2(4);
91 
92 static void dstr_connect(struct pi_adapter *pi)
93 
94 {       pi->saved_r0 = r0();
95         pi->saved_r2 = r2();
96         w2(4); CCP(0xe0); w0(0xff);
97 }
98 
99 static void dstr_disconnect(struct pi_adapter *pi)
100 
101 {       CCP(0x30);
102         w0(pi->saved_r0);
103         w2(pi->saved_r2);
104 }
105 
106 static void dstr_read_block(struct pi_adapter *pi, char *buf, int count)
107 
108 {       int     k, a, b;
109 
110         w0(0x81); P1;
111         if (pi->mode) { w0(0x19); } else { w0(9); }
112 	P2; w0(0x82); P1; P3; w0(0x20); P1;
113 
114         switch (pi->mode) {
115 
116         case 0: for (k=0;k<count;k++) {
117                         w2(6); a = r1(); w2(4);
118                         w2(6); b = r1(); w2(4);
119                         buf[k] = j44(a,b);
120                 }
121                 break;
122 
123         case 1: w0(0);
124                 for (k=0;k<count;k++) {
125                         w2(0x26); buf[k] = r0(); w2(0x24);
126                 }
127                 w2(4);
128                 break;
129 
130         case 2: w2(0x24);
131                 for (k=0;k<count;k++) buf[k] = r4();
132                 w2(4);
133                 break;
134 
135         case 3: w2(0x24);
136                 for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
137                 w2(4);
138                 break;
139 
140         case 4: w2(0x24);
141                 for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
142                 w2(4);
143                 break;
144 
145         }
146 }
147 
148 static void dstr_write_block(struct pi_adapter *pi, char *buf, int count)
149 
150 {       int	k;
151 
152         w0(0x81); P1;
153         if (pi->mode) { w0(0x19); } else { w0(9); }
154         P2; w0(0x82); P1; P3; w0(0x20); P1;
155 
156         switch (pi->mode) {
157 
158         case 0:
159         case 1: for (k=0;k<count;k++) {
160                         w2(5); w0(buf[k]); w2(7);
161                 }
162                 w2(5); w2(4);
163                 break;
164 
165         case 2: w2(0xc5);
166                 for (k=0;k<count;k++) w4(buf[k]);
167 		w2(0xc4);
168                 break;
169 
170         case 3: w2(0xc5);
171                 for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
172                 w2(0xc4);
173                 break;
174 
175         case 4: w2(0xc5);
176                 for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
177                 w2(0xc4);
178                 break;
179 
180         }
181 }
182 
183 
184 static void dstr_log_adapter(struct pi_adapter *pi)
185 
186 {       char    *mode_string[5] = {"4-bit","8-bit","EPP-8",
187 				   "EPP-16","EPP-32"};
188 
189 	dev_info(&pi->dev, "DataStor EP2000 at 0x%x, mode %d (%s), delay %d\n",
190 		pi->port, pi->mode, mode_string[pi->mode], pi->delay);
191 }
192 
193 static struct pi_protocol dstr = {
194 	.owner		= THIS_MODULE,
195 	.name		= "dstr",
196 	.max_mode	= 5,
197 	.epp_first	= 2,
198 	.default_delay	= 1,
199 	.max_units	= 1,
200 	.write_regr	= dstr_write_regr,
201 	.read_regr	= dstr_read_regr,
202 	.write_block	= dstr_write_block,
203 	.read_block	= dstr_read_block,
204 	.connect	= dstr_connect,
205 	.disconnect	= dstr_disconnect,
206 	.log_adapter	= dstr_log_adapter,
207 };
208 
209 MODULE_LICENSE("GPL");
210 module_pata_parport_driver(dstr);
211