OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [before_ORP/] [uclinux/] [uClinux-2.0.x/] [drivers/] [block/] [paride/] [on26.c] - Blame information for rev 199

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
        on26.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
3
                              Under the terms of the GNU public license.
4
 
5
        on26.c is a low-level protocol driver for the
6
        OnSpec 90c26 parallel to IDE adapter chip.
7
 
8
*/
9
 
10
/* Changes:
11
 
12
        1.01    GRG 1998.05.06 init_proto, release_proto
13
        1.02    GRG 1998.09.23 updates for the -E rev chip
14
        1.03    GRG 1998.12.14 fix for slave drives
15
        1.04    GRG 1998.12.20 yet another bug fix
16
 
17
*/
18
 
19
#define ON26_VERSION      "1.04"
20
 
21
#include <linux/module.h>
22
#include <linux/delay.h>
23
#include <linux/kernel.h>
24
#include <linux/types.h>
25
#include <asm/io.h>
26
 
27
#include "paride.h"
28
 
29
/* mode codes:  0  nybble reads, 8-bit writes
30
                1  8-bit reads and writes
31
                2  8-bit EPP mode
32
                3  EPP-16
33
                4  EPP-32
34
*/
35
 
36
#define j44(a,b)  (((a>>4)&0x0f)|(b&0xf0))
37
 
38
#define P1      w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
39
#define P2      w2(5);w2(7);w2(5);w2(4);
40
 
41
/* cont = 0 - access the IDE register file
42
   cont = 1 - access the IDE command set
43
*/
44
 
45
static int on26_read_regr( PIA *pi, int cont, int regr )
46
 
47
{       int     a, b, r;
48
 
49
        r = (regr<<2) + 1 + cont;
50
 
51
        switch (pi->mode)  {
52
 
53
        case 0: w0(1); P1; w0(r); P2; w0(0); P1;
54
                w2(6); a = r1(); w2(4);
55
                w2(6); b = r1(); w2(4);
56
                w2(6); w2(4); w2(6); w2(4);
57
                return j44(a,b);
58
 
59
        case 1: w0(1); P1; w0(r); P2; w0(0); P1;
60
                w2(0x26); a = r0(); w2(4); w2(0x26); w2(4);
61
                return a;
62
 
63
        case 2:
64
        case 3:
65
        case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
66
                w3(0); w3(0); w2(0x24); a = r4(); w2(4);
67
                w2(0x24); r4(); w2(4);
68
                return a;
69
 
70
        }
71
        return -1;
72
}
73
 
74
static void on26_write_regr( PIA *pi, int cont, int regr, int val )
75
 
76
{       int  r;
77
 
78
        r = (regr<<2) + 1 + cont;
79
 
80
        switch (pi->mode)  {
81
 
82
        case 0:
83
        case 1: w0(1); P1; w0(r); P2; w0(0); P1;
84
                w0(val); P2; w0(val); P2;
85
                break;
86
 
87
        case 2:
88
        case 3:
89
        case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
90
                w3(0); w3(0);
91
                w2(5); w4(val); w2(4);
92
                w2(5); w4(val); w2(4);
93
                break;
94
        }
95
}
96
 
97
#define  CCP(x)  w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff);\
98
                 w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
99
 
100
static void on26_connect ( PIA *pi )
101
 
102
{       int     x;
103
 
104
        pi->saved_r0 = r0();
105
        pi->saved_r2 = r2();
106
 
107
        CCP(0x20);
108
        x = 8; if (pi->mode) x = 9;
109
 
110
        w0(2); P1; w0(8); P2;
111
        w0(2); P1; w0(x); P2;
112
}
113
 
114
static void on26_disconnect ( PIA *pi )
115
 
116
{       if (pi->mode >= 2) { w3(4); w3(4); w3(4); w3(4); }
117
                      else { w0(4); P1; w0(4); P1; }
118
        CCP(0x30);
119
        w0(pi->saved_r0);
120
        w2(pi->saved_r2);
121
}
122
 
123
#define RESET_WAIT  200
124
 
125
static int on26_test_port( PIA *pi)  /* hard reset */
126
 
127
{       int     i, m, d, x, y;
128
 
129
        pi->saved_r0 = r0();
130
        pi->saved_r2 = r2();
131
 
132
        d = pi->delay;
133
        m = pi->mode;
134
        pi->delay = 5;
135
        pi->mode = 0;
136
 
137
        w2(0xc);
138
 
139
        CCP(0x30); CCP(0);
140
 
141
        w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff);
142
        i = ((r1() & 0xf0) << 4); w0(0x87);
143
        i |= (r1() & 0xf0); w0(0x78);
144
        w0(0x20);w2(4);w2(5);
145
        i |= ((r1() & 0xf0) >> 4);
146
        w2(4);w0(0xff);
147
 
148
        if (i == 0xb5f) {
149
 
150
            w0(2); P1; w0(0);   P2;
151
            w0(3); P1; w0(0);   P2;
152
            w0(2); P1; w0(8);   P2; udelay(100);
153
            w0(2); P1; w0(0xa); P2; udelay(100);
154
            w0(2); P1; w0(8);   P2; udelay(1000);
155
 
156
            on26_write_regr(pi,0,6,0xa0);
157
 
158
            for (i=0;i<RESET_WAIT;i++) {
159
                on26_write_regr(pi,0,6,0xa0);
160
                x = on26_read_regr(pi,0,7);
161
                on26_write_regr(pi,0,6,0xb0);
162
                y = on26_read_regr(pi,0,7);
163
                if (!((x&0x80)||(y&0x80))) break;
164
                udelay(100000);
165
            }
166
 
167
            if (i == RESET_WAIT)
168
                printk("on26: Device reset failed (%x,%x)\n",x,y);
169
 
170
            w0(4); P1; w0(4); P1;
171
        }
172
 
173
        CCP(0x30);
174
 
175
        pi->delay = d;
176
        pi->mode = m;
177
        w0(pi->saved_r0);
178
        w2(pi->saved_r2);
179
 
180
        return 5;
181
}
182
 
183
 
184
static void on26_read_block( PIA *pi, char * buf, int count )
185
 
186
{       int     k, a, b;
187
 
188
        switch (pi->mode) {
189
 
190
        case 0: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x18); P2; w0(0); P1;
191
                udelay(10);
192
                for (k=0;k<count;k++) {
193
                        w2(6); a = r1();
194
                        w2(4); b = r1();
195
                        buf[k] = j44(a,b);
196
                }
197
                w0(2); P1; w0(8); P2;
198
                break;
199
 
200
        case 1: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1;
201
                udelay(10);
202
                for (k=0;k<count/2;k++) {
203
                        w2(0x26); buf[2*k] = r0();
204
                        w2(0x24); buf[2*k+1] = r0();
205
                }
206
                w0(2); P1; w0(9); P2;
207
                break;
208
 
209
        case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
210
                w3(0); w3(0); w2(0x24);
211
                udelay(10);
212
                for (k=0;k<count;k++) buf[k] = r4();
213
                w2(4);
214
                break;
215
 
216
        case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
217
                w3(0); w3(0); w2(0x24);
218
                udelay(10);
219
                for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
220
                w2(4);
221
                break;
222
 
223
        case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
224
                w3(0); w3(0); w2(0x24);
225
                udelay(10);
226
                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
227
                w2(4);
228
                break;
229
 
230
        }
231
}
232
 
233
static void on26_write_block( PIA *pi, char * buf, int count )
234
 
235
{       int     k;
236
 
237
        switch (pi->mode) {
238
 
239
        case 0:
240
        case 1: w0(1); P1; w0(1); P2;
241
                w0(2); P1; w0(0x18+pi->mode); P2; w0(0); P1;
242
                udelay(10);
243
                for (k=0;k<count/2;k++) {
244
                        w2(5); w0(buf[2*k]);
245
                        w2(7); w0(buf[2*k+1]);
246
                }
247
                w2(5); w2(4);
248
                w0(2); P1; w0(8+pi->mode); P2;
249
                break;
250
 
251
        case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
252
                w3(0); w3(0); w2(0xc5);
253
                udelay(10);
254
                for (k=0;k<count;k++) w4(buf[k]);
255
                w2(0xc4);
256
                break;
257
 
258
        case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
259
                w3(0); w3(0); w2(0xc5);
260
                udelay(10);
261
                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
262
                w2(0xc4);
263
                break;
264
 
265
        case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
266
                w3(0); w3(0); w2(0xc5);
267
                udelay(10);
268
                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
269
                w2(0xc4);
270
                break;
271
 
272
        }
273
 
274
}
275
 
276
static void on26_log_adapter( PIA *pi, char * scratch, int verbose )
277
 
278
{       char    *mode_string[5] = {"4-bit","8-bit","EPP-8",
279
                                   "EPP-16","EPP-32"};
280
 
281
        printk("%s: on26 %s, OnSpec 90c26 at 0x%x, ",
282
                pi->device,ON26_VERSION,pi->port);
283
        printk("mode %d (%s), delay %d\n",pi->mode,
284
                mode_string[pi->mode],pi->delay);
285
 
286
}
287
 
288
static void on26_init_proto( PIA *pi)
289
 
290
{       MOD_INC_USE_COUNT;
291
}
292
 
293
static void on26_release_proto( PIA *pi)
294
 
295
{       MOD_DEC_USE_COUNT;
296
}
297
 
298
struct pi_protocol on26 = {"on26",0,5,2,1,1,
299
                           on26_write_regr,
300
                           on26_read_regr,
301
                           on26_write_block,
302
                           on26_read_block,
303
                           on26_connect,
304
                           on26_disconnect,
305
                           on26_test_port,
306
                           0,
307
                           0,
308
                           on26_log_adapter,
309
                           on26_init_proto,
310
                           on26_release_proto
311
                          };
312
 
313
 
314
#ifdef MODULE
315
 
316
int     init_module(void)
317
 
318
{       return pi_register( &on26 ) - 1;
319
}
320
 
321
void    cleanup_module(void)
322
 
323
{       pi_unregister( &on26 );
324
}
325
 
326
#endif
327
 
328
/* end of on26.c */
329
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.