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