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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
        frpw.c  (c) 1996-8  Grant R. Guenther <grant@torque.net>
3
                            Under the terms of the GNU public license
4
 
5
        frpw.c is a low-level protocol driver for the Freecom "Power"
6
        parallel port IDE adapter.
7
 
8
        Some applications of this adapter may require a "printer" reset
9
        prior to loading the driver.  This can be done by loading and
10
        unloading the "lp" driver, or it can be done by this driver
11
        if you define FRPW_HARD_RESET.  The latter is not recommended
12
        as it may upset devices on other ports.
13
 
14
*/
15
 
16
/* Changes:
17
 
18
        1.01    GRG 1998.05.06 init_proto, release_proto
19
                               fix chip detect
20
                               added EPP-16 and EPP-32
21
        1.02    GRG 1998.09.23 added hard reset to initialisation process
22
        1.03    GRG 1998.12.14 made hard reset conditional
23
 
24
*/
25
 
26
#define FRPW_VERSION    "1.03" 
27
 
28
#include <linux/module.h>
29
#include <linux/delay.h>
30
#include <linux/kernel.h>
31
#include <linux/types.h>
32
#include <asm/io.h>
33
 
34
#include "paride.h"
35
 
36
#define cec4            w2(0xc);w2(0xe);w2(0xe);w2(0xc);w2(4);w2(4);w2(4);
37
#define j44(l,h)        (((l>>4)&0x0f)|(h&0xf0))
38
 
39
/* cont = 0 - access the IDE register file
40
   cont = 1 - access the IDE command set
41
*/
42
 
43
static int  cont_map[2] = { 0x08, 0x10 };
44
 
45
static int frpw_read_regr( PIA *pi, int cont, int regr )
46
 
47
{       int     h,l,r;
48
 
49
        r = regr + cont_map[cont];
50
 
51
        w2(4);
52
        w0(r); cec4;
53
        w2(6); l = r1();
54
        w2(4); h = r1();
55
        w2(4);
56
 
57
        return j44(l,h);
58
 
59
}
60
 
61
static void frpw_write_regr( PIA *pi, int cont, int regr, int val)
62
 
63
{       int r;
64
 
65
        r = regr + cont_map[cont];
66
 
67
        w2(4); w0(r); cec4;
68
        w0(val);
69
        w2(5);w2(7);w2(5);w2(4);
70
}
71
 
72
static void frpw_read_block_int( PIA *pi, char * buf, int count, int regr )
73
 
74
{       int     h, l, k, ph;
75
 
76
        switch(pi->mode) {
77
 
78
        case 0: w2(4); w0(regr); cec4;
79
                for (k=0;k<count;k++) {
80
                        w2(6); l = r1();
81
                        w2(4); h = r1();
82
                        buf[k] = j44(l,h);
83
                }
84
                w2(4);
85
                break;
86
 
87
        case 1: ph = 2;
88
                w2(4); w0(regr + 0xc0); cec4;
89
                w0(0xff);
90
                for (k=0;k<count;k++) {
91
                        w2(0xa4 + ph);
92
                        buf[k] = r0();
93
                        ph = 2 - ph;
94
                }
95
                w2(0xac); w2(0xa4); w2(4);
96
                break;
97
 
98
        case 2: w2(4); w0(regr + 0x80); cec4;
99
                for (k=0;k<count;k++) buf[k] = r4();
100
                w2(0xac); w2(0xa4);
101
                w2(4);
102
                break;
103
 
104
        case 3: w2(4); w0(regr + 0x80); cec4;
105
                for (k=0;k<count-2;k++) buf[k] = r4();
106
                w2(0xac); w2(0xa4);
107
                buf[count-2] = r4();
108
                buf[count-1] = r4();
109
                w2(4);
110
                break;
111
 
112
        case 4: w2(4); w0(regr + 0x80); cec4;
113
                for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
114
                w2(0xac); w2(0xa4);
115
                buf[count-2] = r4();
116
                buf[count-1] = r4();
117
                w2(4);
118
                break;
119
 
120
        case 5: w2(4); w0(regr + 0x80); cec4;
121
                for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
122
                buf[count-4] = r4();
123
                buf[count-3] = r4();
124
                w2(0xac); w2(0xa4);
125
                buf[count-2] = r4();
126
                buf[count-1] = r4();
127
                w2(4);
128
                break;
129
 
130
        }
131
}
132
 
133
static void frpw_read_block( PIA *pi, char * buf, int count)
134
 
135
{       frpw_read_block_int(pi,buf,count,0x08);
136
}
137
 
138
static void frpw_write_block( PIA *pi, char * buf, int count )
139
 
140
{       int     k;
141
 
142
        switch(pi->mode) {
143
 
144
        case 0:
145
        case 1:
146
        case 2: w2(4); w0(8); cec4; w2(5);
147
                for (k=0;k<count;k++) {
148
                        w0(buf[k]);
149
                        w2(7);w2(5);
150
                }
151
                w2(4);
152
                break;
153
 
154
        case 3: w2(4); w0(0xc8); cec4; w2(5);
155
                for (k=0;k<count;k++) w4(buf[k]);
156
                w2(4);
157
                break;
158
 
159
        case 4: w2(4); w0(0xc8); cec4; w2(5);
160
                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
161
                w2(4);
162
                break;
163
 
164
        case 5: w2(4); w0(0xc8); cec4; w2(5);
165
                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
166
                w2(4);
167
                break;
168
        }
169
}
170
 
171
static void frpw_connect ( PIA *pi  )
172
 
173
{       pi->saved_r0 = r0();
174
        pi->saved_r2 = r2();
175
        w2(4);
176
}
177
 
178
static void frpw_disconnect ( PIA *pi )
179
 
180
{       w2(4); w0(0x20); cec4;
181
        w0(pi->saved_r0);
182
        w2(pi->saved_r2);
183
}
184
 
185
/* Stub logic to see if PNP string is available - used to distinguish
186
   between the Xilinx and ASIC implementations of the Freecom adapter.
187
*/
188
 
189
static int frpw_test_pnp ( PIA *pi )
190
 
191
/*  returns chip_type:   0 = Xilinx, 1 = ASIC   */
192
 
193
{       int olddelay, a, b;
194
 
195
#ifdef FRPW_HARD_RESET
196
        w0(0); w2(8); udelay(50); w2(0xc);   /* parallel bus reset */
197
        udelay(1500000);
198
#endif
199
 
200
        olddelay = pi->delay;
201
        pi->delay = 10;
202
 
203
        pi->saved_r0 = r0();
204
        pi->saved_r2 = r2();
205
 
206
        w2(4); w0(4); w2(6); w2(7);
207
        a = r1() & 0xff; w2(4); b = r1() & 0xff;
208
        w2(0xc); w2(0xe); w2(4);
209
 
210
        pi->delay = olddelay;
211
        w0(pi->saved_r0);
212
        w2(pi->saved_r2);
213
 
214
        return ((~a&0x40) && (b&0x40));
215
}
216
 
217
/* We use the pi->private to remember the result of the PNP test.
218
   To make this work, private = port*2 + chip.  Yes, I know it's
219
   a hack :-(
220
*/
221
 
222
static int frpw_test_proto( PIA *pi, char * scratch, int verbose )
223
 
224
{       int     j, k, r;
225
        int     e[2] = {0,0};
226
 
227
        if ((pi->private>>1) != pi->port)
228
           pi->private = frpw_test_pnp(pi) + 2*pi->port;
229
 
230
        if (((pi->private%2) == 0) && (pi->mode > 2)) {
231
           if (verbose)
232
                printk("%s: frpw: Xilinx does not support mode %d\n",
233
                        pi->device, pi->mode);
234
           return 1;
235
        }
236
 
237
        if (((pi->private%2) == 1) && (pi->mode == 2)) {
238
           if (verbose)
239
                printk("%s: frpw: ASIC does not support mode 2\n",
240
                        pi->device);
241
           return 1;
242
        }
243
 
244
        frpw_connect(pi);
245
        for (j=0;j<2;j++) {
246
                frpw_write_regr(pi,0,6,0xa0+j*0x10);
247
                for (k=0;k<256;k++) {
248
                        frpw_write_regr(pi,0,2,k^0xaa);
249
                        frpw_write_regr(pi,0,3,k^0x55);
250
                        if (frpw_read_regr(pi,0,2) != (k^0xaa)) e[j]++;
251
                        }
252
                }
253
        frpw_disconnect(pi);
254
 
255
        frpw_connect(pi);
256
        frpw_read_block_int(pi,scratch,512,0x10);
257
        r = 0;
258
        for (k=0;k<128;k++) if (scratch[k] != k) r++;
259
        frpw_disconnect(pi);
260
 
261
        if (verbose)  {
262
            printk("%s: frpw: port 0x%x, chip %d, mode %d, test=(%d,%d,%d)\n",
263
                   pi->device,pi->port,(pi->private%2),pi->mode,e[0],e[1],r);
264
        }
265
 
266
        return (r || (e[0] && e[1]));
267
}
268
 
269
 
270
static void frpw_log_adapter( PIA *pi, char * scratch, int verbose )
271
 
272
{       char    *mode_string[6] = {"4-bit","8-bit","EPP",
273
                                   "EPP-8","EPP-16","EPP-32"};
274
 
275
        printk("%s: frpw %s, Freecom (%s) adapter at 0x%x, ", pi->device,
276
                FRPW_VERSION,((pi->private%2) == 0)?"Xilinx":"ASIC",pi->port);
277
        printk("mode %d (%s), delay %d\n",pi->mode,
278
                mode_string[pi->mode],pi->delay);
279
 
280
}
281
 
282
static void frpw_init_proto( PIA *pi)
283
 
284
{       MOD_INC_USE_COUNT;
285
        pi->private = 0;
286
}
287
 
288
static void frpw_release_proto( PIA *pi)
289
 
290
{       MOD_DEC_USE_COUNT;
291
}
292
 
293
struct pi_protocol frpw = {"frpw",0,6,2,2,1,
294
                           frpw_write_regr,
295
                           frpw_read_regr,
296
                           frpw_write_block,
297
                           frpw_read_block,
298
                           frpw_connect,
299
                           frpw_disconnect,
300
                           0,
301
                           0,
302
                           frpw_test_proto,
303
                           frpw_log_adapter,
304
                           frpw_init_proto,
305
                           frpw_release_proto
306
                          };
307
 
308
 
309
#ifdef MODULE
310
 
311
int     init_module(void)
312
 
313
{       return pi_register( &frpw ) - 1;
314
}
315
 
316
void    cleanup_module(void)
317
 
318
{       pi_unregister( &frpw );
319
}
320
 
321
#endif
322
 
323
/* end of frpw.c */

powered by: WebSVN 2.1.0

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