epia.c (8049B)
1/* 2 epia.c (c) 1997-8 Grant R. Guenther <grant@torque.net> 3 Under the terms of the GNU General Public License. 4 5 epia.c is a low-level protocol driver for Shuttle Technologies 6 EPIA parallel to IDE adapter chip. This device is now obsolete 7 and has been replaced with the EPAT chip, which is supported 8 by epat.c, however, some devices based on EPIA are still 9 available. 10 11*/ 12 13/* Changes: 14 15 1.01 GRG 1998.05.06 init_proto, release_proto 16 1.02 GRG 1998.06.17 support older versions of EPIA 17 18*/ 19 20#define EPIA_VERSION "1.02" 21 22#include <linux/module.h> 23#include <linux/init.h> 24#include <linux/delay.h> 25#include <linux/kernel.h> 26#include <linux/types.h> 27#include <linux/wait.h> 28#include <asm/io.h> 29 30#include "paride.h" 31 32/* mode codes: 0 nybble reads on port 1, 8-bit writes 33 1 5/3 reads on ports 1 & 2, 8-bit writes 34 2 8-bit reads and writes 35 3 8-bit EPP mode 36 4 16-bit EPP 37 5 32-bit EPP 38*/ 39 40#define j44(a,b) (((a>>4)&0x0f)+(b&0xf0)) 41#define j53(a,b) (((a>>3)&0x1f)+((b<<4)&0xe0)) 42 43/* cont = 0 IDE register file 44 cont = 1 IDE control registers 45*/ 46 47static int cont_map[2] = { 0, 0x80 }; 48 49static int epia_read_regr( PIA *pi, int cont, int regr ) 50 51{ int a, b, r; 52 53 regr += cont_map[cont]; 54 55 switch (pi->mode) { 56 57 case 0: r = regr^0x39; 58 w0(r); w2(1); w2(3); w0(r); 59 a = r1(); w2(1); b = r1(); w2(4); 60 return j44(a,b); 61 62 case 1: r = regr^0x31; 63 w0(r); w2(1); w0(r&0x37); 64 w2(3); w2(5); w0(r|0xf0); 65 a = r1(); b = r2(); w2(4); 66 return j53(a,b); 67 68 case 2: r = regr^0x29; 69 w0(r); w2(1); w2(0X21); w2(0x23); 70 a = r0(); w2(4); 71 return a; 72 73 case 3: 74 case 4: 75 case 5: w3(regr); w2(0x24); a = r4(); w2(4); 76 return a; 77 78 } 79 return -1; 80} 81 82static void epia_write_regr( PIA *pi, int cont, int regr, int val) 83 84{ int r; 85 86 regr += cont_map[cont]; 87 88 switch (pi->mode) { 89 90 case 0: 91 case 1: 92 case 2: r = regr^0x19; 93 w0(r); w2(1); w0(val); w2(3); w2(4); 94 break; 95 96 case 3: 97 case 4: 98 case 5: r = regr^0x40; 99 w3(r); w4(val); w2(4); 100 break; 101 } 102} 103 104#define WR(r,v) epia_write_regr(pi,0,r,v) 105#define RR(r) (epia_read_regr(pi,0,r)) 106 107/* The use of register 0x84 is entirely unclear - it seems to control 108 some EPP counters ... currently we know about 3 different block 109 sizes: the standard 512 byte reads and writes, 12 byte writes and 110 2048 byte reads (the last two being used in the CDrom drivers. 111*/ 112 113static void epia_connect ( PIA *pi ) 114 115{ pi->saved_r0 = r0(); 116 pi->saved_r2 = r2(); 117 118 w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0); 119 w2(1); w2(4); 120 if (pi->mode >= 3) { 121 w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4); 122 w2(0x24); w2(0x26); w2(4); 123 } 124 WR(0x86,8); 125} 126 127static void epia_disconnect ( PIA *pi ) 128 129{ /* WR(0x84,0x10); */ 130 w0(pi->saved_r0); 131 w2(1); w2(4); 132 w0(pi->saved_r0); 133 w2(pi->saved_r2); 134} 135 136static void epia_read_block( PIA *pi, char * buf, int count ) 137 138{ int k, ph, a, b; 139 140 switch (pi->mode) { 141 142 case 0: w0(0x81); w2(1); w2(3); w0(0xc1); 143 ph = 1; 144 for (k=0;k<count;k++) { 145 w2(2+ph); a = r1(); 146 w2(4+ph); b = r1(); 147 buf[k] = j44(a,b); 148 ph = 1 - ph; 149 } 150 w0(0); w2(4); 151 break; 152 153 case 1: w0(0x91); w2(1); w0(0x10); w2(3); 154 w0(0x51); w2(5); w0(0xd1); 155 ph = 1; 156 for (k=0;k<count;k++) { 157 w2(4+ph); 158 a = r1(); b = r2(); 159 buf[k] = j53(a,b); 160 ph = 1 - ph; 161 } 162 w0(0); w2(4); 163 break; 164 165 case 2: w0(0x89); w2(1); w2(0x23); w2(0x21); 166 ph = 1; 167 for (k=0;k<count;k++) { 168 w2(0x24+ph); 169 buf[k] = r0(); 170 ph = 1 - ph; 171 } 172 w2(6); w2(4); 173 break; 174 175 case 3: if (count > 512) WR(0x84,3); 176 w3(0); w2(0x24); 177 for (k=0;k<count;k++) buf[k] = r4(); 178 w2(4); WR(0x84,0); 179 break; 180 181 case 4: if (count > 512) WR(0x84,3); 182 w3(0); w2(0x24); 183 for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w(); 184 w2(4); WR(0x84,0); 185 break; 186 187 case 5: if (count > 512) WR(0x84,3); 188 w3(0); w2(0x24); 189 for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l(); 190 w2(4); WR(0x84,0); 191 break; 192 193 } 194} 195 196static void epia_write_block( PIA *pi, char * buf, int count ) 197 198{ int ph, k, last, d; 199 200 switch (pi->mode) { 201 202 case 0: 203 case 1: 204 case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5); 205 ph = 0; last = 0x8000; 206 for (k=0;k<count;k++) { 207 d = buf[k]; 208 if (d != last) { last = d; w0(d); } 209 w2(4+ph); 210 ph = 1 - ph; 211 } 212 w2(7); w2(4); 213 break; 214 215 case 3: if (count < 512) WR(0x84,1); 216 w3(0x40); 217 for (k=0;k<count;k++) w4(buf[k]); 218 if (count < 512) WR(0x84,0); 219 break; 220 221 case 4: if (count < 512) WR(0x84,1); 222 w3(0x40); 223 for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]); 224 if (count < 512) WR(0x84,0); 225 break; 226 227 case 5: if (count < 512) WR(0x84,1); 228 w3(0x40); 229 for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]); 230 if (count < 512) WR(0x84,0); 231 break; 232 233 } 234 235} 236 237static int epia_test_proto( PIA *pi, char * scratch, int verbose ) 238 239{ int j, k, f; 240 int e[2] = {0,0}; 241 242 epia_connect(pi); 243 for (j=0;j<2;j++) { 244 WR(6,0xa0+j*0x10); 245 for (k=0;k<256;k++) { 246 WR(2,k^0xaa); 247 WR(3,k^0x55); 248 if (RR(2) != (k^0xaa)) e[j]++; 249 } 250 WR(2,1); WR(3,1); 251 } 252 epia_disconnect(pi); 253 254 f = 0; 255 epia_connect(pi); 256 WR(0x84,8); 257 epia_read_block(pi,scratch,512); 258 for (k=0;k<256;k++) { 259 if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++; 260 if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++; 261 } 262 WR(0x84,0); 263 epia_disconnect(pi); 264 265 if (verbose) { 266 printk("%s: epia: port 0x%x, mode %d, test=(%d,%d,%d)\n", 267 pi->device,pi->port,pi->mode,e[0],e[1],f); 268 } 269 270 return (e[0] && e[1]) || f; 271 272} 273 274 275static void epia_log_adapter( PIA *pi, char * scratch, int verbose ) 276 277{ char *mode_string[6] = {"4-bit","5/3","8-bit", 278 "EPP-8","EPP-16","EPP-32"}; 279 280 printk("%s: epia %s, Shuttle EPIA at 0x%x, ", 281 pi->device,EPIA_VERSION,pi->port); 282 printk("mode %d (%s), delay %d\n",pi->mode, 283 mode_string[pi->mode],pi->delay); 284 285} 286 287static struct pi_protocol epia = { 288 .owner = THIS_MODULE, 289 .name = "epia", 290 .max_mode = 6, 291 .epp_first = 3, 292 .default_delay = 1, 293 .max_units = 1, 294 .write_regr = epia_write_regr, 295 .read_regr = epia_read_regr, 296 .write_block = epia_write_block, 297 .read_block = epia_read_block, 298 .connect = epia_connect, 299 .disconnect = epia_disconnect, 300 .test_proto = epia_test_proto, 301 .log_adapter = epia_log_adapter, 302}; 303 304static int __init epia_init(void) 305{ 306 return paride_register(&epia); 307} 308 309static void __exit epia_exit(void) 310{ 311 paride_unregister(&epia); 312} 313 314MODULE_LICENSE("GPL"); 315module_init(epia_init) 316module_exit(epia_exit)