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