^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) on26.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) on26.c is a low-level protocol driver for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) OnSpec 90c26 parallel to IDE adapter chip.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /* Changes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) 1.01 GRG 1998.05.06 init_proto, release_proto
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) 1.02 GRG 1998.09.23 updates for the -E rev chip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) 1.03 GRG 1998.12.14 fix for slave drives
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) 1.04 GRG 1998.12.20 yet another bug fix
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^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) #define ON26_VERSION "1.04"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "paride.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* mode codes: 0 nybble reads, 8-bit writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) 1 8-bit reads and writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) 2 8-bit EPP mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) 3 EPP-16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) 4 EPP-32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define j44(a,b) (((a>>4)&0x0f)|(b&0xf0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define P1 w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define P2 w2(5);w2(7);w2(5);w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* cont = 0 - access the IDE register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) cont = 1 - access the IDE command set
^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 on26_read_regr( PIA *pi, int cont, int regr )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) { int a, b, r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) r = (regr<<2) + 1 + cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) case 0: w0(1); P1; w0(r); P2; w0(0); P1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) w2(6); a = r1(); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) w2(6); b = r1(); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) w2(6); w2(4); w2(6); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return j44(a,b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) case 1: w0(1); P1; w0(r); P2; w0(0); P1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) w2(0x26); a = r0(); w2(4); w2(0x26); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) w3(0); w3(0); w2(0x24); a = r4(); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) w2(0x24); (void)r4(); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) static void on26_write_regr( PIA *pi, int cont, int regr, int val )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) { int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) r = (regr<<2) + 1 + cont;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) case 1: w0(1); P1; w0(r); P2; w0(0); P1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) w0(val); P2; w0(val); P2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) case 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) w3(0); w3(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) w2(5); w4(val); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) w2(5); w4(val); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define CCP(x) w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) static void on26_connect ( PIA *pi )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) { int x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) pi->saved_r0 = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) pi->saved_r2 = r2();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) CCP(0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) x = 8; if (pi->mode) x = 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) w0(2); P1; w0(8); P2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) w0(2); P1; w0(x); P2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static void on26_disconnect ( PIA *pi )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) { if (pi->mode >= 2) { w3(4); w3(4); w3(4); w3(4); }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) else { w0(4); P1; w0(4); P1; }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) CCP(0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) w0(pi->saved_r0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) w2(pi->saved_r2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define RESET_WAIT 200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int on26_test_port( PIA *pi) /* hard reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) { int i, m, d, x=0, y=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) pi->saved_r0 = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) pi->saved_r2 = r2();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) d = pi->delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) m = pi->mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) pi->delay = 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) pi->mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) w2(0xc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) CCP(0x30); CCP(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) i = ((r1() & 0xf0) << 4); w0(0x87);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) i |= (r1() & 0xf0); w0(0x78);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) w0(0x20);w2(4);w2(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) i |= ((r1() & 0xf0) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) w2(4);w0(0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (i == 0xb5f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) w0(2); P1; w0(0); P2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) w0(3); P1; w0(0); P2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) w0(2); P1; w0(8); P2; udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) w0(2); P1; w0(0xa); P2; udelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) w0(2); P1; w0(8); P2; udelay(1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) on26_write_regr(pi,0,6,0xa0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) for (i=0;i<RESET_WAIT;i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) on26_write_regr(pi,0,6,0xa0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) x = on26_read_regr(pi,0,7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) on26_write_regr(pi,0,6,0xb0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) y = on26_read_regr(pi,0,7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (!((x&0x80)||(y&0x80))) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) mdelay(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (i == RESET_WAIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) printk("on26: Device reset failed (%x,%x)\n",x,y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) w0(4); P1; w0(4); P1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) CCP(0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) pi->delay = d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) pi->mode = m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) w0(pi->saved_r0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) w2(pi->saved_r2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static void on26_read_block( PIA *pi, char * buf, int count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) { int k, a, b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) case 0: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x18); P2; w0(0); P1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) for (k=0;k<count;k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) w2(6); a = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) w2(4); b = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) buf[k] = j44(a,b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) w0(2); P1; w0(8); P2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) case 1: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) for (k=0;k<count/2;k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) w2(0x26); buf[2*k] = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) w2(0x24); buf[2*k+1] = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) w0(2); P1; w0(9); P2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) w3(0); w3(0); w2(0x24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) for (k=0;k<count;k++) buf[k] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) w3(0); w3(0); w2(0x24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) w3(0); w3(0); w2(0x24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^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) static void on26_write_block( PIA *pi, char * buf, int count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) { int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) switch (pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) case 1: w0(1); P1; w0(1); P2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) w0(2); P1; w0(0x18+pi->mode); P2; w0(0); P1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) for (k=0;k<count/2;k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) w2(5); w0(buf[2*k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) w2(7); w0(buf[2*k+1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) w2(5); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) w0(2); P1; w0(8+pi->mode); P2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) w3(0); w3(0); w2(0xc5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) for (k=0;k<count;k++) w4(buf[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) w2(0xc4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) w3(0); w3(0); w2(0xc5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) w2(0xc4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) w3(0); w3(0); w2(0xc5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) w2(0xc4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) break;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static void on26_log_adapter( PIA *pi, char * scratch, int verbose )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { char *mode_string[5] = {"4-bit","8-bit","EPP-8",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) "EPP-16","EPP-32"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) printk("%s: on26 %s, OnSpec 90c26 at 0x%x, ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) pi->device,ON26_VERSION,pi->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) printk("mode %d (%s), delay %d\n",pi->mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) mode_string[pi->mode],pi->delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static struct pi_protocol on26 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) .name = "on26",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) .max_mode = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) .epp_first = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) .default_delay = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) .max_units = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .write_regr = on26_write_regr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .read_regr = on26_read_regr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .write_block = on26_write_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) .read_block = on26_read_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) .connect = on26_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) .disconnect = on26_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) .test_port = on26_test_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) .log_adapter = on26_log_adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static int __init on26_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) return paride_register(&on26);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static void __exit on26_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) paride_unregister(&on26);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) module_init(on26_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) module_exit(on26_exit)