Back to home page

OSCL-LXR

 
 

    


0001 /* 
0002         fit3.c        (c) 1998  Grant R. Guenther <grant@torque.net>
0003                           Under the terms of the GNU General Public License.
0004 
0005     fit3.c is a low-level protocol driver for newer models 
0006         of the Fidelity International Technology parallel port adapter.  
0007     This adapter is used in their TransDisk 3000 portable 
0008     hard-drives, as well as CD-ROM, PD-CD and other devices.
0009 
0010     The TD-2000 and certain older devices use a different protocol.
0011     Try the fit2 protocol module with them.
0012 
0013         NB:  The FIT adapters do not appear to support the control 
0014     registers.  So, we map ALT_STATUS to STATUS and NO-OP writes 
0015     to the device control register - this means that IDE reset 
0016     will not work on these devices.
0017 
0018 */
0019 
0020 #define FIT3_VERSION      "1.0"
0021 
0022 #include <linux/module.h>
0023 #include <linux/init.h>
0024 #include <linux/delay.h>
0025 #include <linux/kernel.h>
0026 #include <linux/types.h>
0027 #include <linux/wait.h>
0028 #include <asm/io.h>
0029 
0030 #include "paride.h"
0031 
0032 #define j44(a,b)                (((a>>3)&0x0f)|((b<<1)&0xf0))
0033 
0034 #define w7(byte)                {out_p(7,byte);}
0035 #define r7()                    (in_p(7) & 0xff)
0036 
0037 /* cont = 0 - access the IDE register file 
0038    cont = 1 - access the IDE command set 
0039 
0040 */
0041 
0042 static void  fit3_write_regr( PIA *pi, int cont, int regr, int val)
0043 
0044 {   if (cont == 1) return;
0045 
0046     switch (pi->mode) {
0047 
0048     case 0:
0049     case 1: w2(0xc); w0(regr); w2(0x8); w2(0xc); 
0050         w0(val); w2(0xd); 
0051         w0(0);   w2(0xc);
0052         break;
0053 
0054     case 2: w2(0xc); w0(regr); w2(0x8); w2(0xc);
0055         w4(val); w4(0);
0056         w2(0xc);
0057         break;
0058 
0059     }
0060 }
0061 
0062 static int fit3_read_regr( PIA *pi, int cont, int regr )
0063 
0064 {   int  a, b;
0065 
0066     if (cont) {
0067       if (regr != 6) return 0xff;
0068       regr = 7;
0069     } 
0070 
0071     switch (pi->mode) {
0072 
0073     case 0: w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc);
0074         w2(0xd); a = r1();
0075         w2(0xf); b = r1(); 
0076         w2(0xc);
0077         return j44(a,b);
0078 
0079     case 1: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
0080         w2(0xec); w2(0xee); w2(0xef); a = r0(); 
0081         w2(0xc);
0082         return a;
0083 
0084     case 2: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc); 
0085         w2(0xec); 
0086         a = r4(); b = r4(); 
0087         w2(0xc);
0088         return a;
0089 
0090     }
0091     return -1; 
0092 
0093 }
0094 
0095 static void fit3_read_block( PIA *pi, char * buf, int count )
0096 
0097 {   int  k, a, b, c, d;
0098 
0099     switch (pi->mode) {
0100 
0101     case 0: w2(0xc); w0(0x10); w2(0x8); w2(0xc);
0102         for (k=0;k<count/2;k++) {
0103             w2(0xd); a = r1();
0104             w2(0xf); b = r1();
0105             w2(0xc); c = r1();
0106             w2(0xe); d = r1();
0107             buf[2*k  ] = j44(a,b);
0108             buf[2*k+1] = j44(c,d);
0109         }
0110         w2(0xc);
0111         break;
0112 
0113     case 1: w2(0xc); w0(0x90); w2(0x8); w2(0xc); 
0114         w2(0xec); w2(0xee);
0115         for (k=0;k<count/2;k++) {
0116             w2(0xef); a = r0();
0117             w2(0xee); b = r0();
0118                     buf[2*k  ] = a;
0119                     buf[2*k+1] = b;
0120         }
0121         w2(0xec); 
0122         w2(0xc);
0123         break;
0124 
0125     case 2: w2(0xc); w0(0x90); w2(0x8); w2(0xc); 
0126                 w2(0xec);
0127         for (k=0;k<count;k++) buf[k] = r4();
0128                 w2(0xc);
0129         break;
0130 
0131     }
0132 }
0133 
0134 static void fit3_write_block( PIA *pi, char * buf, int count )
0135 
0136 {   int k;
0137 
0138         switch (pi->mode) {
0139 
0140     case 0:
0141         case 1: w2(0xc); w0(0); w2(0x8); w2(0xc);
0142                 for (k=0;k<count/2;k++) {
0143             w0(buf[2*k  ]); w2(0xd);
0144             w0(buf[2*k+1]); w2(0xc);
0145         }
0146         break;
0147 
0148         case 2: w2(0xc); w0(0); w2(0x8); w2(0xc); 
0149                 for (k=0;k<count;k++) w4(buf[k]);
0150                 w2(0xc);
0151         break;
0152     }
0153 }
0154 
0155 static void fit3_connect ( PIA *pi  )
0156 
0157 {       pi->saved_r0 = r0();
0158         pi->saved_r2 = r2();
0159     w2(0xc); w0(0); w2(0xa);
0160     if (pi->mode == 2) { 
0161         w2(0xc); w0(0x9); w2(0x8); w2(0xc); 
0162         }
0163 }
0164 
0165 static void fit3_disconnect ( PIA *pi )
0166 
0167 {       w2(0xc); w0(0xa); w2(0x8); w2(0xc);
0168     w0(pi->saved_r0);
0169         w2(pi->saved_r2);
0170 } 
0171 
0172 static void fit3_log_adapter( PIA *pi, char * scratch, int verbose )
0173 
0174 {       char    *mode_string[3] = {"4-bit","8-bit","EPP"};
0175 
0176     printk("%s: fit3 %s, FIT 3000 adapter at 0x%x, "
0177            "mode %d (%s), delay %d\n",
0178                 pi->device,FIT3_VERSION,pi->port,
0179         pi->mode,mode_string[pi->mode],pi->delay);
0180 
0181 }
0182 
0183 static struct pi_protocol fit3 = {
0184     .owner      = THIS_MODULE,
0185     .name       = "fit3",
0186     .max_mode   = 3,
0187     .epp_first  = 2,
0188     .default_delay  = 1,
0189     .max_units  = 1,
0190     .write_regr = fit3_write_regr,
0191     .read_regr  = fit3_read_regr,
0192     .write_block    = fit3_write_block,
0193     .read_block = fit3_read_block,
0194     .connect    = fit3_connect,
0195     .disconnect = fit3_disconnect,
0196     .log_adapter    = fit3_log_adapter,
0197 };
0198 
0199 static int __init fit3_init(void)
0200 {
0201     return paride_register(&fit3);
0202 }
0203 
0204 static void __exit fit3_exit(void)
0205 {
0206     paride_unregister(&fit3);
0207 }
0208 
0209 MODULE_LICENSE("GPL");
0210 module_init(fit3_init)
0211 module_exit(fit3_exit)