1 /* 2 on20.c (c) 1996-8 Grant R. Guenther <grant@torque.net> 3 Under the terms of the GNU General Public License. 4 5 on20.c is a low-level protocol driver for the 6 Onspec 90c20 parallel to IDE adapter. 7 */ 8 9 #include <linux/module.h> 10 #include <linux/init.h> 11 #include <linux/delay.h> 12 #include <linux/kernel.h> 13 #include <linux/types.h> 14 #include <linux/wait.h> 15 #include <asm/io.h> 16 #include "pata_parport.h" 17 18 #define op(f) w2(4);w0(f);w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4); 19 #define vl(v) w2(4);w0(v);w2(5);w2(7);w2(5);w2(4); 20 21 #define j44(a,b) (((a>>4)&0x0f)|(b&0xf0)) 22 23 /* cont = 0 - access the IDE register file 24 cont = 1 - access the IDE command set 25 */ 26 27 static int on20_read_regr(struct pi_adapter *pi, int cont, int regr) 28 29 { int h,l, r ; 30 31 r = (regr<<2) + 1 + cont; 32 33 op(1); vl(r); op(0); 34 35 switch (pi->mode) { 36 37 case 0: w2(4); w2(6); l = r1(); 38 w2(4); w2(6); h = r1(); 39 w2(4); w2(6); w2(4); w2(6); w2(4); 40 return j44(l,h); 41 42 case 1: w2(4); w2(0x26); r = r0(); 43 w2(4); w2(0x26); w2(4); 44 return r; 45 46 } 47 return -1; 48 } 49 50 static void on20_write_regr(struct pi_adapter *pi, int cont, int regr, int val) 51 52 { int r; 53 54 r = (regr<<2) + 1 + cont; 55 56 op(1); vl(r); 57 op(0); vl(val); 58 op(0); vl(val); 59 } 60 61 static void on20_connect(struct pi_adapter *pi) 62 63 { pi->saved_r0 = r0(); 64 pi->saved_r2 = r2(); 65 66 w2(4);w0(0);w2(0xc);w2(4);w2(6);w2(4);w2(6);w2(4); 67 if (pi->mode) { op(2); vl(8); op(2); vl(9); } 68 else { op(2); vl(0); op(2); vl(8); } 69 } 70 71 static void on20_disconnect(struct pi_adapter *pi) 72 73 { w2(4);w0(7);w2(4);w2(0xc);w2(4); 74 w0(pi->saved_r0); 75 w2(pi->saved_r2); 76 } 77 78 static void on20_read_block(struct pi_adapter *pi, char *buf, int count) 79 80 { int k, l, h; 81 82 op(1); vl(1); op(0); 83 84 for (k=0;k<count;k++) 85 if (pi->mode) { 86 w2(4); w2(0x26); buf[k] = r0(); 87 } else { 88 w2(6); l = r1(); w2(4); 89 w2(6); h = r1(); w2(4); 90 buf[k] = j44(l,h); 91 } 92 w2(4); 93 } 94 95 static void on20_write_block(struct pi_adapter *pi, char *buf, int count) 96 97 { int k; 98 99 op(1); vl(1); op(0); 100 101 for (k=0;k<count;k++) { w2(5); w0(buf[k]); w2(7); } 102 w2(4); 103 } 104 105 static void on20_log_adapter(struct pi_adapter *pi) 106 107 { char *mode_string[2] = {"4-bit","8-bit"}; 108 109 dev_info(&pi->dev, "OnSpec 90c20 at 0x%x, mode %d (%s), delay %d\n", 110 pi->port, pi->mode, mode_string[pi->mode], pi->delay); 111 } 112 113 static struct pi_protocol on20 = { 114 .owner = THIS_MODULE, 115 .name = "on20", 116 .max_mode = 2, 117 .epp_first = 2, 118 .default_delay = 1, 119 .max_units = 1, 120 .write_regr = on20_write_regr, 121 .read_regr = on20_read_regr, 122 .write_block = on20_write_block, 123 .read_block = on20_read_block, 124 .connect = on20_connect, 125 .disconnect = on20_disconnect, 126 .log_adapter = on20_log_adapter, 127 }; 128 129 MODULE_LICENSE("GPL"); 130 module_pata_parport_driver(on20); 131