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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [block/] [paride/] [bpck.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
        bpck.c  (c) 1996-8  Grant R. Guenther <grant@torque.net>
3
                            Under the terms of the GNU public license.
4
 
5
        bpck.c is a low-level protocol driver for the MicroSolutions
6
        "backpack" parallel port IDE adapter.
7
 
8
*/
9
 
10
/* Changes:
11
 
12
        1.01    GRG 1998.05.05 init_proto, release_proto, pi->delay
13
        1.02    GRG 1998.08.15 default pi->delay returned to 4
14
 
15
*/
16
 
17
#define BPCK_VERSION    "1.02" 
18
 
19
#include <linux/module.h>
20
#include <linux/delay.h>
21
#include <linux/kernel.h>
22
#include <linux/types.h>
23
#include <asm/io.h>
24
 
25
#include "paride.h"
26
 
27
#undef r2
28
#undef w2
29
 
30
#define PC                      pi->private
31
#define r2()                    (PC=(in_p(2) & 0xff))
32
#define w2(byte)                {out_p(2,byte); PC = byte;}
33
#define t2(pat)                 {PC ^= pat; out_p(2,PC);}
34
#define e2()                    {PC &= 0xfe; out_p(2,PC);}
35
#define o2()                    {PC |= 1; out_p(2,PC);}
36
 
37
#define j44(l,h)     (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80))
38
 
39
/* cont = 0 - access the IDE register file
40
   cont = 1 - access the IDE command set
41
   cont = 2 - use internal bpck register addressing
42
*/
43
 
44
static int  cont_map[3] = { 0x40, 0x48, 0 };
45
 
46
static int bpck_read_regr( PIA *pi, int cont, int regr )
47
 
48
{       int r, l, h;
49
 
50
        r = regr + cont_map[cont];
51
 
52
        switch (pi->mode) {
53
 
54
        case 0: w0(r & 0xf); w0(r); t2(2); t2(4);
55
                l = r1();
56
                t2(4);
57
                h = r1();
58
                return j44(l,h);
59
 
60
        case 1: w0(r & 0xf); w0(r); t2(2);
61
                e2(); t2(0x20);
62
                t2(4); h = r0();
63
                t2(1); t2(0x20);
64
                return h;
65
 
66
        case 2:
67
        case 3:
68
        case 4: w0(r); w2(9); w2(0); w2(0x20);
69
                h = r4();
70
                w2(0);
71
                return h;
72
 
73
        }
74
        return -1;
75
}
76
 
77
static void bpck_write_regr( PIA *pi, int cont, int regr, int val )
78
 
79
{       int     r;
80
 
81
        r = regr + cont_map[cont];
82
 
83
        switch (pi->mode) {
84
 
85
        case 0:
86
        case 1: w0(r);
87
                t2(2);
88
                w0(val);
89
                o2(); t2(4); t2(1);
90
                break;
91
 
92
        case 2:
93
        case 3:
94
        case 4: w0(r); w2(9); w2(0);
95
                w0(val); w2(1); w2(3); w2(0);
96
                break;
97
 
98
        }
99
}
100
 
101
/* These macros access the bpck registers in native addressing */
102
 
103
#define WR(r,v)         bpck_write_regr(pi,2,r,v)
104
#define RR(r)           (bpck_read_regr(pi,2,r))
105
 
106
static void bpck_write_block( PIA *pi, char * buf, int count )
107
 
108
{       int i;
109
 
110
        switch (pi->mode) {
111
 
112
        case 0: WR(4,0x40);
113
                w0(0x40); t2(2); t2(1);
114
                for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
115
                WR(4,0);
116
                break;
117
 
118
        case 1: WR(4,0x50);
119
                w0(0x40); t2(2); t2(1);
120
                for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
121
                WR(4,0x10);
122
                break;
123
 
124
        case 2: WR(4,0x48);
125
                w0(0x40); w2(9); w2(0); w2(1);
126
                for (i=0;i<count;i++) w4(buf[i]);
127
                w2(0);
128
                WR(4,8);
129
                break;
130
 
131
        case 3: WR(4,0x48);
132
                w0(0x40); w2(9); w2(0); w2(1);
133
                for (i=0;i<count/2;i++) w4w(((u16 *)buf)[i]);
134
                w2(0);
135
                WR(4,8);
136
                break;
137
 
138
        case 4: WR(4,0x48);
139
                w0(0x40); w2(9); w2(0); w2(1);
140
                for (i=0;i<count/4;i++) w4l(((u32 *)buf)[i]);
141
                w2(0);
142
                WR(4,8);
143
                break;
144
        }
145
}
146
 
147
static void bpck_read_block( PIA *pi, char * buf, int count )
148
 
149
{       int i, l, h;
150
 
151
        switch (pi->mode) {
152
 
153
        case 0: WR(4,0x40);
154
                w0(0x40); t2(2);
155
                for (i=0;i<count;i++) {
156
                    t2(4); l = r1();
157
                    t2(4); h = r1();
158
                    buf[i] = j44(l,h);
159
                }
160
                WR(4,0);
161
                break;
162
 
163
        case 1: WR(4,0x50);
164
                w0(0x40); t2(2); t2(0x20);
165
                for(i=0;i<count;i++) { t2(4); buf[i] = r0(); }
166
                t2(1); t2(0x20);
167
                WR(4,0x10);
168
                break;
169
 
170
        case 2: WR(4,0x48);
171
                w0(0x40); w2(9); w2(0); w2(0x20);
172
                for (i=0;i<count;i++) buf[i] = r4();
173
                w2(0);
174
                WR(4,8);
175
                break;
176
 
177
        case 3: WR(4,0x48);
178
                w0(0x40); w2(9); w2(0); w2(0x20);
179
                for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
180
                w2(0);
181
                WR(4,8);
182
                break;
183
 
184
        case 4: WR(4,0x48);
185
                w0(0x40); w2(9); w2(0); w2(0x20);
186
                for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
187
                w2(0);
188
                WR(4,8);
189
                break;
190
 
191
        }
192
}
193
 
194
static int bpck_probe_unit ( PIA *pi )
195
 
196
{       int o1, o0, f7, id;
197
        int t, s;
198
 
199
        id = pi->unit;
200
        s = 0;
201
        w2(4); w2(0xe); r2(); t2(2);
202
        o1 = r1()&0xf8;
203
        o0 = r0();
204
        w0(255-id); w2(4); w0(id);
205
        t2(8); t2(8); t2(8);
206
        t2(2); t = r1()&0xf8;
207
        f7 = ((id % 8) == 7);
208
        if ((f7) || (t != o1)) { t2(2); s = r1()&0xf8; }
209
        if ((t == o1) && ((!f7) || (s == o1)))  {
210
                w2(0x4c); w0(o0);
211
                return 0;
212
        }
213
        t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
214
        return 1;
215
}
216
 
217
static void bpck_connect ( PIA *pi  )
218
 
219
{       pi->saved_r0 = r0();
220
        w0(0xff-pi->unit); w2(4); w0(pi->unit);
221
        t2(8); t2(8); t2(8);
222
        t2(2); t2(2);
223
 
224
        switch (pi->mode) {
225
 
226
        case 0: t2(8); WR(4,0);
227
                break;
228
 
229
        case 1: t2(8); WR(4,0x10);
230
                break;
231
 
232
        case 2:
233
        case 3:
234
        case 4: w2(0); WR(4,8);
235
                break;
236
 
237
        }
238
 
239
        WR(5,8);
240
 
241
        if (pi->devtype == PI_PCD) {
242
                WR(0x46,0x10);          /* fiddle with ESS logic ??? */
243
                WR(0x4c,0x38);
244
                WR(0x4d,0x88);
245
                WR(0x46,0xa0);
246
                WR(0x41,0);
247
                WR(0x4e,8);
248
                }
249
}
250
 
251
static void bpck_disconnect ( PIA *pi )
252
 
253
{       w0(0);
254
        if (pi->mode >= 2) { w2(9); w2(0); } else t2(2);
255
        w2(0x4c); w0(pi->saved_r0);
256
}
257
 
258
static void bpck_force_spp ( PIA *pi )
259
 
260
/* This fakes the EPP protocol to turn off EPP ... */
261
 
262
{       pi->saved_r0 = r0();
263
        w0(0xff-pi->unit); w2(4); w0(pi->unit);
264
        t2(8); t2(8); t2(8);
265
        t2(2); t2(2);
266
 
267
        w2(0);
268
        w0(4); w2(9); w2(0);
269
        w0(0); w2(1); w2(3); w2(0);
270
        w0(0); w2(9); w2(0);
271
        w2(0x4c); w0(pi->saved_r0);
272
}
273
 
274
#define TEST_LEN  16
275
 
276
static int bpck_test_proto( PIA *pi, char * scratch, int verbose )
277
 
278
{       int i, e, l, h, om;
279
        char buf[TEST_LEN];
280
 
281
        bpck_force_spp(pi);
282
 
283
        switch (pi->mode) {
284
 
285
        case 0: bpck_connect(pi);
286
                WR(0x13,0x7f);
287
                w0(0x13); t2(2);
288
                for(i=0;i<TEST_LEN;i++) {
289
                    t2(4); l = r1();
290
                    t2(4); h = r1();
291
                    buf[i] = j44(l,h);
292
                }
293
                bpck_disconnect(pi);
294
                break;
295
 
296
        case 1: bpck_connect(pi);
297
                WR(0x13,0x7f);
298
                w0(0x13); t2(2); t2(0x20);
299
                for(i=0;i<TEST_LEN;i++) { t2(4); buf[i] = r0(); }
300
                t2(1); t2(0x20);
301
                bpck_disconnect(pi);
302
                break;
303
 
304
        case 2:
305
        case 3:
306
        case 4: om = pi->mode;
307
                pi->mode = 0;
308
                bpck_connect(pi);
309
                WR(7,3);
310
                WR(4,8);
311
                bpck_disconnect(pi);
312
 
313
                pi->mode = om;
314
                bpck_connect(pi);
315
                w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
316
 
317
                switch (pi->mode) {
318
                  case 2: for (i=0;i<TEST_LEN;i++) buf[i] = r4();
319
                          break;
320
                  case 3: for (i=0;i<TEST_LEN/2;i++) ((u16 *)buf)[i] = r4w();
321
                          break;
322
                  case 4: for (i=0;i<TEST_LEN/4;i++) ((u32 *)buf)[i] = r4l();
323
                          break;
324
                }
325
 
326
                w2(0);
327
                WR(7,0);
328
                bpck_disconnect(pi);
329
 
330
                break;
331
 
332
        }
333
 
334
        if (verbose) {
335
            printk("%s: bpck: 0x%x unit %d mode %d: ",
336
                   pi->device,pi->port,pi->unit,pi->mode);
337
            for (i=0;i<TEST_LEN;i++) printk("%3d",buf[i]);
338
            printk("\n");
339
        }
340
 
341
        e = 0;
342
        for (i=0;i<TEST_LEN;i++) if (buf[i] != (i+1)) e++;
343
        return e;
344
}
345
 
346
static void bpck_read_eeprom ( PIA *pi, char * buf )
347
 
348
{       int i,j,k,n,p,v,f, om, od;
349
 
350
        bpck_force_spp(pi);
351
 
352
        om = pi->mode;  od = pi->delay;
353
        pi->mode = 0; pi->delay = 6;
354
 
355
        bpck_connect(pi);
356
 
357
        n = 0;
358
        WR(4,0);
359
        for (i=0;i<64;i++) {
360
            WR(6,8);
361
            WR(6,0xc);
362
            p = 0x100;
363
            for (k=0;k<9;k++) {
364
                f = (((i + 0x180) & p) != 0) * 2;
365
                WR(6,f+0xc);
366
                WR(6,f+0xd);
367
                WR(6,f+0xc);
368
                p = (p >> 1);
369
            }
370
            for (j=0;j<2;j++) {
371
                v = 0;
372
                for (k=0;k<8;k++) {
373
                    WR(6,0xc);
374
                    WR(6,0xd);
375
                    WR(6,0xc);
376
                    f = RR(0);
377
                    v = 2*v + (f == 0x84);
378
                }
379
                buf[2*i+1-j] = v;
380
            }
381
        }
382
        WR(6,8);
383
        WR(6,0);
384
        WR(5,8);
385
 
386
        bpck_disconnect(pi);
387
 
388
        if (om >= 2) {
389
                bpck_connect(pi);
390
                WR(7,3);
391
                WR(4,8);
392
                bpck_disconnect(pi);
393
        }
394
 
395
        pi->mode = om; pi->delay = od;
396
}
397
 
398
static int bpck_test_port ( PIA *pi )   /* check for 8-bit port */
399
 
400
{       int     i, r, m;
401
 
402
        w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
403
        m = -1;
404
        if (r == i) m = 2;
405
        if (r == (255-i)) m = 0;
406
 
407
        w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i);
408
        if (r != (255-i)) m = -1;
409
 
410
        if (m == 0) { w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa); }
411
        if (m == 2) { w2(0x26); w2(0xc); }
412
 
413
        if (m == -1) return 0;
414
        return 5;
415
}
416
 
417
static void bpck_log_adapter( PIA *pi, char * scratch, int verbose )
418
 
419
{       char    *mode_string[5] = { "4-bit","8-bit","EPP-8",
420
                                    "EPP-16","EPP-32" };
421
 
422
#ifdef DUMP_EEPROM
423
        int i;
424
#endif
425
 
426
        bpck_read_eeprom(pi,scratch);
427
 
428
#ifdef DUMP_EEPROM
429
        if (verbose) {
430
           for(i=0;i<128;i++)
431
                if ((scratch[i] < ' ') || (scratch[i] > '~'))
432
                    scratch[i] = '.';
433
           printk("%s: bpck EEPROM: %64.64s\n",pi->device,scratch);
434
           printk("%s:              %64.64s\n",pi->device,&scratch[64]);
435
        }
436
#endif
437
 
438
        printk("%s: bpck %s, backpack %8.8s unit %d",
439
                pi->device,BPCK_VERSION,&scratch[110],pi->unit);
440
        printk(" at 0x%x, mode %d (%s), delay %d\n",pi->port,
441
                pi->mode,mode_string[pi->mode],pi->delay);
442
}
443
 
444
static void bpck_init_proto( PIA *pi)
445
 
446
{       MOD_INC_USE_COUNT;
447
}
448
 
449
static void bpck_release_proto( PIA *pi)
450
 
451
{       MOD_DEC_USE_COUNT;
452
}
453
 
454
struct pi_protocol bpck = { "bpck",0,5,2,4,256,
455
                          bpck_write_regr,
456
                          bpck_read_regr,
457
                          bpck_write_block,
458
                          bpck_read_block,
459
                          bpck_connect,
460
                          bpck_disconnect,
461
                          bpck_test_port,
462
                          bpck_probe_unit,
463
                          bpck_test_proto,
464
                          bpck_log_adapter,
465
                          bpck_init_proto,
466
                          bpck_release_proto
467
                        };
468
 
469
#ifdef MODULE
470
 
471
int     init_module(void)
472
 
473
{       return pi_register(&bpck) - 1;
474
}
475
 
476
void    cleanup_module(void)
477
 
478
{       pi_unregister(&bpck);
479
}
480
 
481
#endif
482
 
483
/* end of bpck.c */

powered by: WebSVN 2.1.0

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