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)         fit3.c        (c) 1998  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) 	fit3.c is a low-level protocol driver for newer models 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)         of the Fidelity International Technology parallel port adapter.  
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 	This adapter is used in their TransDisk 3000 portable 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 	hard-drives, as well as CD-ROM, PD-CD and other devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 	The TD-2000 and certain older devices use a different protocol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 	Try the fit2 protocol module with them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)         NB:  The FIT adapters do not appear to support the control 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 	registers.  So, we map ALT_STATUS to STATUS and NO-OP writes 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 	to the device control register - this means that IDE reset 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 	will not work on these devices.
^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 FIT3_VERSION      "1.0"
^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) #define j44(a,b)                (((a>>3)&0x0f)|((b<<1)&0xf0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define w7(byte)                {out_p(7,byte);}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define r7()                    (in_p(7) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) /* cont = 0 - access the IDE register file 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)    cont = 1 - access the IDE command set 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static void  fit3_write_regr( PIA *pi, int cont, int regr, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {	if (cont == 1) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	case 1: w2(0xc); w0(regr); w2(0x8); w2(0xc); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		w0(val); w2(0xd); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		w0(0);   w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	case 2: w2(0xc); w0(regr); w2(0x8); w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		w4(val); w4(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) static int fit3_read_regr( PIA *pi, int cont, int regr )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) {	int  a, b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (cont) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	  if (regr != 6) return 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	  regr = 7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	} 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	case 0: w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 		w2(0xd); a = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		w2(0xf); b = r1(); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		return j44(a,b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	case 1: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		w2(0xec); w2(0xee); w2(0xef); a = r0(); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	case 2: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		w2(0xec); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		a = r4(); b = r4(); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	return -1; 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) static void fit3_read_block( PIA *pi, char * buf, int count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) {	int  k, a, b, c, d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	case 0: w2(0xc); w0(0x10); w2(0x8); w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		for (k=0;k<count/2;k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		    w2(0xd); a = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		    w2(0xf); b = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		    w2(0xc); c = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		    w2(0xe); d = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		    buf[2*k  ] = j44(a,b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		    buf[2*k+1] = j44(c,d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	case 1: w2(0xc); w0(0x90); w2(0x8); w2(0xc); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		w2(0xec); w2(0xee);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		for (k=0;k<count/2;k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		    w2(0xef); a = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		    w2(0xee); b = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)                     buf[2*k  ] = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)                     buf[2*k+1] = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		w2(0xec); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	case 2: w2(0xc); w0(0x90); w2(0x8); w2(0xc); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)                 w2(0xec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		for (k=0;k<count;k++) buf[k] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)                 w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) static void fit3_write_block( PIA *pi, char * buf, int count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) {	int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)         switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)         case 1: w2(0xc); w0(0); w2(0x8); w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)                 for (k=0;k<count/2;k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  		    w0(buf[2*k  ]); w2(0xd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  		    w0(buf[2*k+1]); w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)         case 2: w2(0xc); w0(0); w2(0x8); w2(0xc); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)                 for (k=0;k<count;k++) w4(buf[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)                 w2(0xc);
^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) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static void fit3_connect ( PIA *pi  )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {       pi->saved_r0 = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)         pi->saved_r2 = r2();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	w2(0xc); w0(0); w2(0xa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	if (pi->mode == 2) { 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		w2(0xc); w0(0x9); w2(0x8); w2(0xc); 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static void fit3_disconnect ( PIA *pi )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {       w2(0xc); w0(0xa); w2(0x8); w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	w0(pi->saved_r0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)         w2(pi->saved_r2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) } 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static void fit3_log_adapter( PIA *pi, char * scratch, int verbose )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) {       char    *mode_string[3] = {"4-bit","8-bit","EPP"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	printk("%s: fit3 %s, FIT 3000 adapter at 0x%x, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	       "mode %d (%s), delay %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)                 pi->device,FIT3_VERSION,pi->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		pi->mode,mode_string[pi->mode],pi->delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static struct pi_protocol fit3 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	.owner		= THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	.name		= "fit3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	.max_mode	= 3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	.epp_first	= 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	.default_delay	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	.max_units	= 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	.write_regr	= fit3_write_regr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	.read_regr	= fit3_read_regr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	.write_block	= fit3_write_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	.read_block	= fit3_read_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	.connect	= fit3_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	.disconnect	= fit3_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	.log_adapter	= fit3_log_adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) static int __init fit3_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	return paride_register(&fit3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) static void __exit fit3_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	paride_unregister(&fit3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) module_init(fit3_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) module_exit(fit3_exit)