Back to home page

OSCL-LXR

 
 

    


0001 /* 
0002         aten.c  (c) 1997-8  Grant R. Guenther <grant@torque.net>
0003                             Under the terms of the GNU General Public License.
0004 
0005     aten.c is a low-level protocol driver for the ATEN EH-100
0006     parallel port adapter.  The EH-100 supports 4-bit and 8-bit
0007         modes only.  There is also an EH-132 which supports EPP mode
0008         transfers.  The EH-132 is not yet supported.
0009 
0010 */
0011 
0012 /* Changes:
0013 
0014     1.01    GRG 1998.05.05  init_proto, release_proto
0015 
0016 */
0017 
0018 #define ATEN_VERSION      "1.01"
0019 
0020 #include <linux/module.h>
0021 #include <linux/init.h>
0022 #include <linux/delay.h>
0023 #include <linux/kernel.h>
0024 #include <linux/wait.h>
0025 #include <linux/types.h>
0026 #include <asm/io.h>
0027 
0028 #include "paride.h"
0029 
0030 #define j44(a,b)                ((((a>>4)&0x0f)|(b&0xf0))^0x88)
0031 
0032 /* cont = 0 - access the IDE register file 
0033    cont = 1 - access the IDE command set 
0034 */
0035 
0036 static int  cont_map[2] = { 0x08, 0x20 };
0037 
0038 static void  aten_write_regr( PIA *pi, int cont, int regr, int val)
0039 
0040 {   int r;
0041 
0042     r = regr + cont_map[cont] + 0x80;
0043 
0044     w0(r); w2(0xe); w2(6); w0(val); w2(7); w2(6); w2(0xc);
0045 }
0046 
0047 static int aten_read_regr( PIA *pi, int cont, int regr )
0048 
0049 {   int  a, b, r;
0050 
0051         r = regr + cont_map[cont] + 0x40;
0052 
0053     switch (pi->mode) {
0054 
0055         case 0: w0(r); w2(0xe); w2(6); 
0056         w2(7); w2(6); w2(0);
0057         a = r1(); w0(0x10); b = r1(); w2(0xc);
0058         return j44(a,b);
0059 
0060         case 1: r |= 0x10;
0061         w0(r); w2(0xe); w2(6); w0(0xff); 
0062         w2(0x27); w2(0x26); w2(0x20);
0063         a = r0();
0064         w2(0x26); w2(0xc);
0065         return a;
0066     }
0067     return -1;
0068 }
0069 
0070 static void aten_read_block( PIA *pi, char * buf, int count )
0071 
0072 {   int  k, a, b, c, d;
0073 
0074     switch (pi->mode) {
0075 
0076     case 0: w0(0x48); w2(0xe); w2(6);
0077         for (k=0;k<count/2;k++) {
0078             w2(7); w2(6); w2(2);
0079             a = r1(); w0(0x58); b = r1();
0080             w2(0); d = r1(); w0(0x48); c = r1();
0081             buf[2*k] = j44(c,d);
0082             buf[2*k+1] = j44(a,b);
0083         }
0084         w2(0xc);
0085         break;
0086 
0087     case 1: w0(0x58); w2(0xe); w2(6);
0088         for (k=0;k<count/2;k++) {
0089             w2(0x27); w2(0x26); w2(0x22);
0090             a = r0(); w2(0x20); b = r0();
0091             buf[2*k] = b; buf[2*k+1] = a;
0092         }
0093         w2(0x26); w2(0xc);
0094         break;
0095     }
0096 }
0097 
0098 static void aten_write_block( PIA *pi, char * buf, int count )
0099 
0100 {   int k;
0101 
0102     w0(0x88); w2(0xe); w2(6);
0103     for (k=0;k<count/2;k++) {
0104         w0(buf[2*k+1]); w2(0xe); w2(6);
0105         w0(buf[2*k]); w2(7); w2(6);
0106     }
0107     w2(0xc);
0108 }
0109 
0110 static void aten_connect ( PIA *pi  )
0111 
0112 {       pi->saved_r0 = r0();
0113         pi->saved_r2 = r2();
0114     w2(0xc);    
0115 }
0116 
0117 static void aten_disconnect ( PIA *pi )
0118 
0119 {       w0(pi->saved_r0);
0120         w2(pi->saved_r2);
0121 } 
0122 
0123 static void aten_log_adapter( PIA *pi, char * scratch, int verbose )
0124 
0125 {       char    *mode_string[2] = {"4-bit","8-bit"};
0126 
0127         printk("%s: aten %s, ATEN EH-100 at 0x%x, ",
0128                 pi->device,ATEN_VERSION,pi->port);
0129         printk("mode %d (%s), delay %d\n",pi->mode,
0130         mode_string[pi->mode],pi->delay);
0131 
0132 }
0133 
0134 static struct pi_protocol aten = {
0135     .owner      = THIS_MODULE,
0136     .name       = "aten",
0137     .max_mode   = 2,
0138     .epp_first  = 2,
0139     .default_delay  = 1,
0140     .max_units  = 1,
0141     .write_regr = aten_write_regr,
0142     .read_regr  = aten_read_regr,
0143     .write_block    = aten_write_block,
0144     .read_block = aten_read_block,
0145     .connect    = aten_connect,
0146     .disconnect = aten_disconnect,
0147     .log_adapter    = aten_log_adapter,
0148 };
0149 
0150 static int __init aten_init(void)
0151 {
0152     return paride_register(&aten);
0153 }
0154 
0155 static void __exit aten_exit(void)
0156 {
0157     paride_unregister( &aten );
0158 }
0159 
0160 MODULE_LICENSE("GPL");
0161 module_init(aten_init)
0162 module_exit(aten_exit)