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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [block/] [paride/] [friq.c] - Blame information for rev 1777

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

Line No. Rev Author Line
1 1626 jcastillo
/*
2
        friq.c  (c) 1998    Grant R. Guenther <grant@torque.net>
3
                            Under the terms of the GNU public license
4
 
5
        friq.c is a low-level protocol driver for the Freecom "IQ"
6
        parallel port IDE adapter.   Early versions of this adapter
7
        use the 'frpw' protocol.
8
 
9
        Freecom uses this adapter in a battery powered external
10
        CD-ROM drive.  It is also used in LS-120 drives by
11
        Maxell and Panasonic, and other devices.
12
 
13
        The battery powered drive requires software support to
14
        control the power to the drive.  This module enables the
15
        drive power when the high level driver (pcd) is loaded
16
        and disables it when the module is unloaded.  Note, if
17
        the friq module is built in to the kernel, the power
18
        will never be switched off, so other means should be
19
        used to conserve battery power.
20
 
21
*/
22
 
23
/* Changes:
24
 
25
        1.01    GRG 1998.12.20   Added support for soft power switch
26
*/
27
 
28
#define FRIQ_VERSION    "1.01" 
29
 
30
#include <linux/module.h>
31
#include <linux/delay.h>
32
#include <linux/kernel.h>
33
#include <linux/types.h>
34
#include <asm/io.h>
35
 
36
#include "paride.h"
37
 
38
#define CMD(x)          w2(4);w0(0xff);w0(0xff);w0(0x73);w0(0x73);\
39
                        w0(0xc9);w0(0xc9);w0(0x26);w0(0x26);w0(x);w0(x);
40
 
41
#define j44(l,h)        (((l>>4)&0x0f)|(h&0xf0))
42
 
43
/* cont = 0 - access the IDE register file
44
   cont = 1 - access the IDE command set
45
*/
46
 
47
static int  cont_map[2] = { 0x08, 0x10 };
48
 
49
static int friq_read_regr( PIA *pi, int cont, int regr )
50
 
51
{       int     h,l,r;
52
 
53
        r = regr + cont_map[cont];
54
 
55
        CMD(r);
56
        w2(6); l = r1();
57
        w2(4); h = r1();
58
        w2(4);
59
 
60
        return j44(l,h);
61
 
62
}
63
 
64
static void friq_write_regr( PIA *pi, int cont, int regr, int val)
65
 
66
{       int r;
67
 
68
        r = regr + cont_map[cont];
69
 
70
        CMD(r);
71
        w0(val);
72
        w2(5);w2(7);w2(5);w2(4);
73
}
74
 
75
static void friq_read_block_int( PIA *pi, char * buf, int count, int regr )
76
 
77
{       int     h, l, k, ph;
78
 
79
        switch(pi->mode) {
80
 
81
        case 0: CMD(regr);
82
                for (k=0;k<count;k++) {
83
                        w2(6); l = r1();
84
                        w2(4); h = r1();
85
                        buf[k] = j44(l,h);
86
                }
87
                w2(4);
88
                break;
89
 
90
        case 1: ph = 2;
91
                CMD(regr+0xc0);
92
                w0(0xff);
93
                for (k=0;k<count;k++) {
94
                        w2(0xa4 + ph);
95
                        buf[k] = r0();
96
                        ph = 2 - ph;
97
                }
98
                w2(0xac); w2(0xa4); w2(4);
99
                break;
100
 
101
        case 2: CMD(regr+0x80);
102
                for (k=0;k<count-2;k++) buf[k] = r4();
103
                w2(0xac); w2(0xa4);
104
                buf[count-2] = r4();
105
                buf[count-1] = r4();
106
                w2(4);
107
                break;
108
 
109
        case 3: CMD(regr+0x80);
110
                for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
111
                w2(0xac); w2(0xa4);
112
                buf[count-2] = r4();
113
                buf[count-1] = r4();
114
                w2(4);
115
                break;
116
 
117
        case 4: CMD(regr+0x80);
118
                for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
119
                buf[count-4] = r4();
120
                buf[count-3] = r4();
121
                w2(0xac); w2(0xa4);
122
                buf[count-2] = r4();
123
                buf[count-1] = r4();
124
                w2(4);
125
                break;
126
 
127
        }
128
}
129
 
130
static void friq_read_block( PIA *pi, char * buf, int count)
131
 
132
{       friq_read_block_int(pi,buf,count,0x08);
133
}
134
 
135
static void friq_write_block( PIA *pi, char * buf, int count )
136
 
137
{       int     k;
138
 
139
        switch(pi->mode) {
140
 
141
        case 0:
142
        case 1: CMD(8); w2(5);
143
                for (k=0;k<count;k++) {
144
                        w0(buf[k]);
145
                        w2(7);w2(5);
146
                }
147
                w2(4);
148
                break;
149
 
150
        case 2: CMD(0xc8); w2(5);
151
                for (k=0;k<count;k++) w4(buf[k]);
152
                w2(4);
153
                break;
154
 
155
        case 3: CMD(0xc8); w2(5);
156
                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
157
                w2(4);
158
                break;
159
 
160
        case 4: CMD(0xc8); w2(5);
161
                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
162
                w2(4);
163
                break;
164
        }
165
}
166
 
167
static void friq_connect ( PIA *pi  )
168
 
169
{       pi->saved_r0 = r0();
170
        pi->saved_r2 = r2();
171
        w2(4);
172
}
173
 
174
static void friq_disconnect ( PIA *pi )
175
 
176
{       CMD(0x20);
177
        w0(pi->saved_r0);
178
        w2(pi->saved_r2);
179
}
180
 
181
static int friq_test_proto( PIA *pi, char * scratch, int verbose )
182
 
183
{       int     j, k, r;
184
        int     e[2] = {0,0};
185
 
186
        pi->saved_r0 = r0();
187
        w0(0xff); udelay(20); CMD(0x3d); /* turn the power on */
188
        udelay(500);
189
        w0(pi->saved_r0);
190
 
191
        friq_connect(pi);
192
        for (j=0;j<2;j++) {
193
                friq_write_regr(pi,0,6,0xa0+j*0x10);
194
                for (k=0;k<256;k++) {
195
                        friq_write_regr(pi,0,2,k^0xaa);
196
                        friq_write_regr(pi,0,3,k^0x55);
197
                        if (friq_read_regr(pi,0,2) != (k^0xaa)) e[j]++;
198
                        }
199
                }
200
        friq_disconnect(pi);
201
 
202
        friq_connect(pi);
203
        friq_read_block_int(pi,scratch,512,0x10);
204
        r = 0;
205
        for (k=0;k<128;k++) if (scratch[k] != k) r++;
206
        friq_disconnect(pi);
207
 
208
        if (verbose)  {
209
            printk("%s: friq: port 0x%x, mode %d, test=(%d,%d,%d)\n",
210
                   pi->device,pi->port,pi->mode,e[0],e[1],r);
211
        }
212
 
213
        return (r || (e[0] && e[1]));
214
}
215
 
216
 
217
static void friq_log_adapter( PIA *pi, char * scratch, int verbose )
218
 
219
{       char    *mode_string[6] = {"4-bit","8-bit",
220
                                   "EPP-8","EPP-16","EPP-32"};
221
 
222
        printk("%s: friq %s, Freecom IQ ASIC-2 adapter at 0x%x, ", pi->device,
223
                FRIQ_VERSION,pi->port);
224
        printk("mode %d (%s), delay %d\n",pi->mode,
225
                mode_string[pi->mode],pi->delay);
226
 
227
        pi->private = 1;
228
        friq_connect(pi);
229
        CMD(0x9e);              /* disable sleep timer */
230
        friq_disconnect(pi);
231
 
232
}
233
 
234
static void friq_init_proto( PIA *pi)
235
 
236
{       MOD_INC_USE_COUNT;
237
        pi->private = 0;
238
}
239
 
240
static void friq_release_proto( PIA *pi)
241
 
242
{       if (pi->private) {              /* turn off the power */
243
                friq_connect(pi);
244
                CMD(0x1d); CMD(0x1e);
245
                friq_disconnect(pi);
246
                pi->private = 0;
247
        }
248
 
249
        MOD_DEC_USE_COUNT;
250
}
251
 
252
struct pi_protocol friq = {"friq",0,5,2,1,1,
253
                           friq_write_regr,
254
                           friq_read_regr,
255
                           friq_write_block,
256
                           friq_read_block,
257
                           friq_connect,
258
                           friq_disconnect,
259
                           0,
260
                           0,
261
                           friq_test_proto,
262
                           friq_log_adapter,
263
                           friq_init_proto,
264
                           friq_release_proto
265
                          };
266
 
267
 
268
#ifdef MODULE
269
 
270
int     init_module(void)
271
 
272
{       return pi_register( &friq ) - 1;
273
}
274
 
275
void    cleanup_module(void)
276
 
277
{       pi_unregister( &friq );
278
}
279
 
280
#endif
281
 
282
/* end of friq.c */

powered by: WebSVN 2.1.0

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