Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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)