1/* 2 aten.c (c) 1997-8 Grant R. Guenther <grant@torque.net> 3 Under the terms of the GNU General Public License. 4 5 aten.c is a low-level protocol driver for the ATEN EH-100 6 parallel port adapter. The EH-100 supports 4-bit and 8-bit 7 modes only. There is also an EH-132 which supports EPP mode 8 transfers. The EH-132 is not yet supported. 9 10*/ 11 12/* Changes: 13 14 1.01 GRG 1998.05.05 init_proto, release_proto 15 16*/ 17 18#define ATEN_VERSION "1.01" 19 20#include <linux/module.h> 21#include <linux/delay.h> 22#include <linux/kernel.h> 23#include <linux/wait.h> 24#include <linux/types.h> 25#include <asm/io.h> 26 27#include "paride.h" 28 29#define j44(a,b) ((((a>>4)&0x0f)|(b&0xf0))^0x88) 30 31/* cont = 0 - access the IDE register file 32 cont = 1 - access the IDE command set 33*/ 34 35static int cont_map[2] = { 0x08, 0x20 }; 36 37static void aten_write_regr( PIA *pi, int cont, int regr, int val) 38 39{ int r; 40 41 r = regr + cont_map[cont] + 0x80; 42 43 w0(r); w2(0xe); w2(6); w0(val); w2(7); w2(6); w2(0xc); 44} 45 46static int aten_read_regr( PIA *pi, int cont, int regr ) 47 48{ int a, b, r; 49 50 r = regr + cont_map[cont] + 0x40; 51 52 switch (pi->mode) { 53 54 case 0: w0(r); w2(0xe); w2(6); 55 w2(7); w2(6); w2(0); 56 a = r1(); w0(0x10); b = r1(); w2(0xc); 57 return j44(a,b); 58 59 case 1: r |= 0x10; 60 w0(r); w2(0xe); w2(6); w0(0xff); 61 w2(0x27); w2(0x26); w2(0x20); 62 a = r0(); 63 w2(0x26); w2(0xc); 64 return a; 65 } 66 return -1; 67} 68 69static void aten_read_block( PIA *pi, char * buf, int count ) 70 71{ int k, a, b, c, d; 72 73 switch (pi->mode) { 74 75 case 0: w0(0x48); w2(0xe); w2(6); 76 for (k=0;k<count/2;k++) { 77 w2(7); w2(6); w2(2); 78 a = r1(); w0(0x58); b = r1(); 79 w2(0); d = r1(); w0(0x48); c = r1(); 80 buf[2*k] = j44(c,d); 81 buf[2*k+1] = j44(a,b); 82 } 83 w2(0xc); 84 break; 85 86 case 1: w0(0x58); w2(0xe); w2(6); 87 for (k=0;k<count/2;k++) { 88 w2(0x27); w2(0x26); w2(0x22); 89 a = r0(); w2(0x20); b = r0(); 90 buf[2*k] = b; buf[2*k+1] = a; 91 } 92 w2(0x26); w2(0xc); 93 break; 94 } 95} 96 97static void aten_write_block( PIA *pi, char * buf, int count ) 98 99{ int k; 100 101 w0(0x88); w2(0xe); w2(6); 102 for (k=0;k<count/2;k++) { 103 w0(buf[2*k+1]); w2(0xe); w2(6); 104 w0(buf[2*k]); w2(7); w2(6); 105 } 106 w2(0xc); 107} 108 109static void aten_connect ( PIA *pi ) 110 111{ pi->saved_r0 = r0(); 112 pi->saved_r2 = r2(); 113 w2(0xc); 114} 115 116static void aten_disconnect ( PIA *pi ) 117 118{ w0(pi->saved_r0); 119 w2(pi->saved_r2); 120} 121 122static void aten_log_adapter( PIA *pi, char * scratch, int verbose ) 123 124{ char *mode_string[2] = {"4-bit","8-bit"}; 125 126 printk("%s: aten %s, ATEN EH-100 at 0x%x, ", 127 pi->device,ATEN_VERSION,pi->port); 128 printk("mode %d (%s), delay %d\n",pi->mode, 129 mode_string[pi->mode],pi->delay); 130 131} 132 133static void aten_init_proto( PIA *pi ) 134 135{ MOD_INC_USE_COUNT; 136} 137 138static void aten_release_proto( PIA *pi ) 139 140{ MOD_DEC_USE_COUNT; 141} 142 143struct pi_protocol aten = {"aten",0,2,2,1,1, 144 aten_write_regr, 145 aten_read_regr, 146 aten_write_block, 147 aten_read_block, 148 aten_connect, 149 aten_disconnect, 150 0, 151 0, 152 0, 153 aten_log_adapter, 154 aten_init_proto, 155 aten_release_proto 156 }; 157 158 159#ifdef MODULE 160 161int init_module(void) 162 163{ return pi_register( &aten ) - 1; 164} 165 166void cleanup_module(void) 167 168{ pi_unregister( &aten ); 169} 170 171#endif 172 173/* end of aten.c */ 174MODULE_LICENSE("GPL"); 175