Back to home page

OSCL-LXR

 
 

    


0001 /* 
0002         comm.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
0003                               Under the terms of the GNU General Public License.
0004 
0005     comm.c is a low-level protocol driver for some older models
0006     of the DataStor "Commuter" parallel to IDE adapter.  Some of
0007     the parallel port devices marketed by Arista currently
0008     use this adapter.
0009 */
0010 
0011 /* Changes:
0012 
0013     1.01    GRG 1998.05.05  init_proto, release_proto
0014 
0015 */
0016 
0017 #define COMM_VERSION      "1.01"
0018 
0019 #include <linux/module.h>
0020 #include <linux/init.h>
0021 #include <linux/delay.h>
0022 #include <linux/kernel.h>
0023 #include <linux/types.h>
0024 #include <linux/wait.h>
0025 #include <asm/io.h>
0026 
0027 #include "paride.h"
0028 
0029 /* mode codes:  0  nybble reads, 8-bit writes
0030                 1  8-bit reads and writes
0031                 2  8-bit EPP mode
0032 */
0033 
0034 #define j44(a,b)    (((a>>3)&0x0f)|((b<<1)&0xf0))
0035 
0036 #define P1  w2(5);w2(0xd);w2(0xd);w2(5);w2(4);
0037 #define P2  w2(5);w2(7);w2(7);w2(5);w2(4);
0038 
0039 /* cont = 0 - access the IDE register file 
0040    cont = 1 - access the IDE command set 
0041 */
0042 
0043 static int  cont_map[2] = { 0x08, 0x10 };
0044 
0045 static int comm_read_regr( PIA *pi, int cont, int regr )
0046 
0047 {       int     l, h, r;
0048 
0049         r = regr + cont_map[cont];
0050 
0051         switch (pi->mode)  {
0052 
0053         case 0: w0(r); P1; w0(0);
0054             w2(6); l = r1(); w0(0x80); h = r1(); w2(4);
0055                 return j44(l,h);
0056 
0057         case 1: w0(r+0x20); P1; 
0058             w0(0); w2(0x26); h = r0(); w2(4);
0059                 return h;
0060 
0061     case 2:
0062     case 3:
0063         case 4: w3(r+0x20); (void)r1();
0064             w2(0x24); h = r4(); w2(4);
0065                 return h;
0066 
0067         }
0068         return -1;
0069 }       
0070 
0071 static void comm_write_regr( PIA *pi, int cont, int regr, int val )
0072 
0073 {       int  r;
0074 
0075         r = regr + cont_map[cont];
0076 
0077         switch (pi->mode)  {
0078 
0079         case 0:
0080         case 1: w0(r); P1; w0(val); P2;
0081         break;
0082 
0083     case 2:
0084     case 3:
0085         case 4: w3(r); (void)r1(); w4(val);
0086                 break;
0087         }
0088 }
0089 
0090 static void comm_connect ( PIA *pi  )
0091 
0092 {       pi->saved_r0 = r0();
0093         pi->saved_r2 = r2();
0094         w2(4); w0(0xff); w2(6);
0095         w2(4); w0(0xaa); w2(6);
0096         w2(4); w0(0x00); w2(6);
0097         w2(4); w0(0x87); w2(6);
0098         w2(4); w0(0xe0); w2(0xc); w2(0xc); w2(4);
0099 }
0100 
0101 static void comm_disconnect ( PIA *pi )
0102 
0103 {       w2(0); w2(0); w2(0); w2(4); 
0104     w0(pi->saved_r0);
0105         w2(pi->saved_r2);
0106 } 
0107 
0108 static void comm_read_block( PIA *pi, char * buf, int count )
0109 
0110 {       int     i, l, h;
0111 
0112         switch (pi->mode) {
0113         
0114         case 0: w0(0x48); P1;
0115                 for(i=0;i<count;i++) {
0116                         w0(0); w2(6); l = r1();
0117                         w0(0x80); h = r1(); w2(4);
0118                         buf[i] = j44(l,h);
0119                 }
0120                 break;
0121 
0122         case 1: w0(0x68); P1; w0(0);
0123                 for(i=0;i<count;i++) {
0124                         w2(0x26); buf[i] = r0(); w2(0x24);
0125                 }
0126         w2(4);
0127         break;
0128         
0129     case 2: w3(0x68); (void)r1(); w2(0x24);
0130         for (i=0;i<count;i++) buf[i] = r4();
0131         w2(4);
0132         break;
0133 
0134         case 3: w3(0x68); (void)r1(); w2(0x24);
0135                 for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
0136                 w2(4);
0137                 break;
0138 
0139         case 4: w3(0x68); (void)r1(); w2(0x24);
0140                 for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
0141                 w2(4);
0142                 break;
0143         
0144     }
0145 }
0146 
0147 /* NB: Watch out for the byte swapped writes ! */
0148 
0149 static void comm_write_block( PIA *pi, char * buf, int count )
0150 
0151 {       int k;
0152 
0153         switch (pi->mode) {
0154 
0155         case 0:
0156         case 1: w0(0x68); P1;
0157             for (k=0;k<count;k++) {
0158                         w2(5); w0(buf[k^1]); w2(7);
0159                 }
0160                 w2(5); w2(4);
0161                 break;
0162 
0163         case 2: w3(0x48); (void)r1();
0164                 for (k=0;k<count;k++) w4(buf[k^1]);
0165                 break;
0166 
0167         case 3: w3(0x48); (void)r1();
0168                 for (k=0;k<count/2;k++) w4w(pi_swab16(buf,k));
0169                 break;
0170 
0171         case 4: w3(0x48); (void)r1();
0172                 for (k=0;k<count/4;k++) w4l(pi_swab32(buf,k));
0173                 break;
0174 
0175 
0176         }
0177 }
0178 
0179 static void comm_log_adapter( PIA *pi, char * scratch, int verbose )
0180 
0181 {       char    *mode_string[5] = {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"};
0182 
0183         printk("%s: comm %s, DataStor Commuter at 0x%x, ",
0184                 pi->device,COMM_VERSION,pi->port);
0185         printk("mode %d (%s), delay %d\n",pi->mode,
0186         mode_string[pi->mode],pi->delay);
0187 
0188 }
0189 
0190 static struct pi_protocol comm = {
0191     .owner      = THIS_MODULE,
0192     .name       = "comm",
0193     .max_mode   = 5,
0194     .epp_first  = 2,
0195     .default_delay  = 1,
0196     .max_units  = 1,
0197     .write_regr = comm_write_regr,
0198     .read_regr  = comm_read_regr,
0199     .write_block    = comm_write_block,
0200     .read_block = comm_read_block,
0201     .connect    = comm_connect,
0202     .disconnect = comm_disconnect,
0203     .log_adapter    = comm_log_adapter,
0204 };
0205 
0206 static int __init comm_init(void)
0207 {
0208     return paride_register(&comm);
0209 }
0210 
0211 static void __exit comm_exit(void)
0212 {
0213     paride_unregister(&comm);
0214 }
0215 
0216 MODULE_LICENSE("GPL");
0217 module_init(comm_init)
0218 module_exit(comm_exit)