0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #define BPCK_VERSION "1.02"
0018
0019 #include <linux/module.h>
0020 #include <linux/init.h>
0021 #include <linux/delay.h>
0022 #include <linux/kernel.h>
0023 #include <linux/types.h>
0024 #include <linux/wait.h>
0025 #include <asm/io.h>
0026
0027 #include "paride.h"
0028
0029 #undef r2
0030 #undef w2
0031 #undef PC
0032
0033 #define PC pi->private
0034 #define r2() (PC=(in_p(2) & 0xff))
0035 #define w2(byte) {out_p(2,byte); PC = byte;}
0036 #define t2(pat) {PC ^= pat; out_p(2,PC);}
0037 #define e2() {PC &= 0xfe; out_p(2,PC);}
0038 #define o2() {PC |= 1; out_p(2,PC);}
0039
0040 #define j44(l,h) (((l>>3)&0x7)|((l>>4)&0x8)|((h<<1)&0x70)|(h&0x80))
0041
0042
0043
0044
0045
0046
0047 static int cont_map[3] = { 0x40, 0x48, 0 };
0048
0049 static int bpck_read_regr( PIA *pi, int cont, int regr )
0050
0051 { int r, l, h;
0052
0053 r = regr + cont_map[cont];
0054
0055 switch (pi->mode) {
0056
0057 case 0: w0(r & 0xf); w0(r); t2(2); t2(4);
0058 l = r1();
0059 t2(4);
0060 h = r1();
0061 return j44(l,h);
0062
0063 case 1: w0(r & 0xf); w0(r); t2(2);
0064 e2(); t2(0x20);
0065 t2(4); h = r0();
0066 t2(1); t2(0x20);
0067 return h;
0068
0069 case 2:
0070 case 3:
0071 case 4: w0(r); w2(9); w2(0); w2(0x20);
0072 h = r4();
0073 w2(0);
0074 return h;
0075
0076 }
0077 return -1;
0078 }
0079
0080 static void bpck_write_regr( PIA *pi, int cont, int regr, int val )
0081
0082 { int r;
0083
0084 r = regr + cont_map[cont];
0085
0086 switch (pi->mode) {
0087
0088 case 0:
0089 case 1: w0(r);
0090 t2(2);
0091 w0(val);
0092 o2(); t2(4); t2(1);
0093 break;
0094
0095 case 2:
0096 case 3:
0097 case 4: w0(r); w2(9); w2(0);
0098 w0(val); w2(1); w2(3); w2(0);
0099 break;
0100
0101 }
0102 }
0103
0104
0105
0106 #define WR(r,v) bpck_write_regr(pi,2,r,v)
0107 #define RR(r) (bpck_read_regr(pi,2,r))
0108
0109 static void bpck_write_block( PIA *pi, char * buf, int count )
0110
0111 { int i;
0112
0113 switch (pi->mode) {
0114
0115 case 0: WR(4,0x40);
0116 w0(0x40); t2(2); t2(1);
0117 for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
0118 WR(4,0);
0119 break;
0120
0121 case 1: WR(4,0x50);
0122 w0(0x40); t2(2); t2(1);
0123 for (i=0;i<count;i++) { w0(buf[i]); t2(4); }
0124 WR(4,0x10);
0125 break;
0126
0127 case 2: WR(4,0x48);
0128 w0(0x40); w2(9); w2(0); w2(1);
0129 for (i=0;i<count;i++) w4(buf[i]);
0130 w2(0);
0131 WR(4,8);
0132 break;
0133
0134 case 3: WR(4,0x48);
0135 w0(0x40); w2(9); w2(0); w2(1);
0136 for (i=0;i<count/2;i++) w4w(((u16 *)buf)[i]);
0137 w2(0);
0138 WR(4,8);
0139 break;
0140
0141 case 4: WR(4,0x48);
0142 w0(0x40); w2(9); w2(0); w2(1);
0143 for (i=0;i<count/4;i++) w4l(((u32 *)buf)[i]);
0144 w2(0);
0145 WR(4,8);
0146 break;
0147 }
0148 }
0149
0150 static void bpck_read_block( PIA *pi, char * buf, int count )
0151
0152 { int i, l, h;
0153
0154 switch (pi->mode) {
0155
0156 case 0: WR(4,0x40);
0157 w0(0x40); t2(2);
0158 for (i=0;i<count;i++) {
0159 t2(4); l = r1();
0160 t2(4); h = r1();
0161 buf[i] = j44(l,h);
0162 }
0163 WR(4,0);
0164 break;
0165
0166 case 1: WR(4,0x50);
0167 w0(0x40); t2(2); t2(0x20);
0168 for(i=0;i<count;i++) { t2(4); buf[i] = r0(); }
0169 t2(1); t2(0x20);
0170 WR(4,0x10);
0171 break;
0172
0173 case 2: WR(4,0x48);
0174 w0(0x40); w2(9); w2(0); w2(0x20);
0175 for (i=0;i<count;i++) buf[i] = r4();
0176 w2(0);
0177 WR(4,8);
0178 break;
0179
0180 case 3: WR(4,0x48);
0181 w0(0x40); w2(9); w2(0); w2(0x20);
0182 for (i=0;i<count/2;i++) ((u16 *)buf)[i] = r4w();
0183 w2(0);
0184 WR(4,8);
0185 break;
0186
0187 case 4: WR(4,0x48);
0188 w0(0x40); w2(9); w2(0); w2(0x20);
0189 for (i=0;i<count/4;i++) ((u32 *)buf)[i] = r4l();
0190 w2(0);
0191 WR(4,8);
0192 break;
0193
0194 }
0195 }
0196
0197 static int bpck_probe_unit ( PIA *pi )
0198
0199 { int o1, o0, f7, id;
0200 int t, s;
0201
0202 id = pi->unit;
0203 s = 0;
0204 w2(4); w2(0xe); r2(); t2(2);
0205 o1 = r1()&0xf8;
0206 o0 = r0();
0207 w0(255-id); w2(4); w0(id);
0208 t2(8); t2(8); t2(8);
0209 t2(2); t = r1()&0xf8;
0210 f7 = ((id % 8) == 7);
0211 if ((f7) || (t != o1)) { t2(2); s = r1()&0xf8; }
0212 if ((t == o1) && ((!f7) || (s == o1))) {
0213 w2(0x4c); w0(o0);
0214 return 0;
0215 }
0216 t2(8); w0(0); t2(2); w2(0x4c); w0(o0);
0217 return 1;
0218 }
0219
0220 static void bpck_connect ( PIA *pi )
0221
0222 { pi->saved_r0 = r0();
0223 w0(0xff-pi->unit); w2(4); w0(pi->unit);
0224 t2(8); t2(8); t2(8);
0225 t2(2); t2(2);
0226
0227 switch (pi->mode) {
0228
0229 case 0: t2(8); WR(4,0);
0230 break;
0231
0232 case 1: t2(8); WR(4,0x10);
0233 break;
0234
0235 case 2:
0236 case 3:
0237 case 4: w2(0); WR(4,8);
0238 break;
0239
0240 }
0241
0242 WR(5,8);
0243
0244 if (pi->devtype == PI_PCD) {
0245 WR(0x46,0x10);
0246 WR(0x4c,0x38);
0247 WR(0x4d,0x88);
0248 WR(0x46,0xa0);
0249 WR(0x41,0);
0250 WR(0x4e,8);
0251 }
0252 }
0253
0254 static void bpck_disconnect ( PIA *pi )
0255
0256 { w0(0);
0257 if (pi->mode >= 2) { w2(9); w2(0); } else t2(2);
0258 w2(0x4c); w0(pi->saved_r0);
0259 }
0260
0261 static void bpck_force_spp ( PIA *pi )
0262
0263
0264
0265 { pi->saved_r0 = r0();
0266 w0(0xff-pi->unit); w2(4); w0(pi->unit);
0267 t2(8); t2(8); t2(8);
0268 t2(2); t2(2);
0269
0270 w2(0);
0271 w0(4); w2(9); w2(0);
0272 w0(0); w2(1); w2(3); w2(0);
0273 w0(0); w2(9); w2(0);
0274 w2(0x4c); w0(pi->saved_r0);
0275 }
0276
0277 #define TEST_LEN 16
0278
0279 static int bpck_test_proto( PIA *pi, char * scratch, int verbose )
0280
0281 { int i, e, l, h, om;
0282 char buf[TEST_LEN];
0283
0284 bpck_force_spp(pi);
0285
0286 switch (pi->mode) {
0287
0288 case 0: bpck_connect(pi);
0289 WR(0x13,0x7f);
0290 w0(0x13); t2(2);
0291 for(i=0;i<TEST_LEN;i++) {
0292 t2(4); l = r1();
0293 t2(4); h = r1();
0294 buf[i] = j44(l,h);
0295 }
0296 bpck_disconnect(pi);
0297 break;
0298
0299 case 1: bpck_connect(pi);
0300 WR(0x13,0x7f);
0301 w0(0x13); t2(2); t2(0x20);
0302 for(i=0;i<TEST_LEN;i++) { t2(4); buf[i] = r0(); }
0303 t2(1); t2(0x20);
0304 bpck_disconnect(pi);
0305 break;
0306
0307 case 2:
0308 case 3:
0309 case 4: om = pi->mode;
0310 pi->mode = 0;
0311 bpck_connect(pi);
0312 WR(7,3);
0313 WR(4,8);
0314 bpck_disconnect(pi);
0315
0316 pi->mode = om;
0317 bpck_connect(pi);
0318 w0(0x13); w2(9); w2(1); w0(0); w2(3); w2(0); w2(0xe0);
0319
0320 switch (pi->mode) {
0321 case 2: for (i=0;i<TEST_LEN;i++) buf[i] = r4();
0322 break;
0323 case 3: for (i=0;i<TEST_LEN/2;i++) ((u16 *)buf)[i] = r4w();
0324 break;
0325 case 4: for (i=0;i<TEST_LEN/4;i++) ((u32 *)buf)[i] = r4l();
0326 break;
0327 }
0328
0329 w2(0);
0330 WR(7,0);
0331 bpck_disconnect(pi);
0332
0333 break;
0334
0335 }
0336
0337 if (verbose) {
0338 printk("%s: bpck: 0x%x unit %d mode %d: ",
0339 pi->device,pi->port,pi->unit,pi->mode);
0340 for (i=0;i<TEST_LEN;i++) printk("%3d",buf[i]);
0341 printk("\n");
0342 }
0343
0344 e = 0;
0345 for (i=0;i<TEST_LEN;i++) if (buf[i] != (i+1)) e++;
0346 return e;
0347 }
0348
0349 static void bpck_read_eeprom ( PIA *pi, char * buf )
0350
0351 { int i, j, k, p, v, f, om, od;
0352
0353 bpck_force_spp(pi);
0354
0355 om = pi->mode; od = pi->delay;
0356 pi->mode = 0; pi->delay = 6;
0357
0358 bpck_connect(pi);
0359
0360 WR(4,0);
0361 for (i=0;i<64;i++) {
0362 WR(6,8);
0363 WR(6,0xc);
0364 p = 0x100;
0365 for (k=0;k<9;k++) {
0366 f = (((i + 0x180) & p) != 0) * 2;
0367 WR(6,f+0xc);
0368 WR(6,f+0xd);
0369 WR(6,f+0xc);
0370 p = (p >> 1);
0371 }
0372 for (j=0;j<2;j++) {
0373 v = 0;
0374 for (k=0;k<8;k++) {
0375 WR(6,0xc);
0376 WR(6,0xd);
0377 WR(6,0xc);
0378 f = RR(0);
0379 v = 2*v + (f == 0x84);
0380 }
0381 buf[2*i+1-j] = v;
0382 }
0383 }
0384 WR(6,8);
0385 WR(6,0);
0386 WR(5,8);
0387
0388 bpck_disconnect(pi);
0389
0390 if (om >= 2) {
0391 bpck_connect(pi);
0392 WR(7,3);
0393 WR(4,8);
0394 bpck_disconnect(pi);
0395 }
0396
0397 pi->mode = om; pi->delay = od;
0398 }
0399
0400 static int bpck_test_port ( PIA *pi )
0401
0402 { int i, r, m;
0403
0404 w2(0x2c); i = r0(); w0(255-i); r = r0(); w0(i);
0405 m = -1;
0406 if (r == i) m = 2;
0407 if (r == (255-i)) m = 0;
0408
0409 w2(0xc); i = r0(); w0(255-i); r = r0(); w0(i);
0410 if (r != (255-i)) m = -1;
0411
0412 if (m == 0) { w2(6); w2(0xc); r = r0(); w0(0xaa); w0(r); w0(0xaa); }
0413 if (m == 2) { w2(0x26); w2(0xc); }
0414
0415 if (m == -1) return 0;
0416 return 5;
0417 }
0418
0419 static void bpck_log_adapter( PIA *pi, char * scratch, int verbose )
0420
0421 { char *mode_string[5] = { "4-bit","8-bit","EPP-8",
0422 "EPP-16","EPP-32" };
0423
0424 #ifdef DUMP_EEPROM
0425 int i;
0426 #endif
0427
0428 bpck_read_eeprom(pi,scratch);
0429
0430 #ifdef DUMP_EEPROM
0431 if (verbose) {
0432 for(i=0;i<128;i++)
0433 if ((scratch[i] < ' ') || (scratch[i] > '~'))
0434 scratch[i] = '.';
0435 printk("%s: bpck EEPROM: %64.64s\n",pi->device,scratch);
0436 printk("%s: %64.64s\n",pi->device,&scratch[64]);
0437 }
0438 #endif
0439
0440 printk("%s: bpck %s, backpack %8.8s unit %d",
0441 pi->device,BPCK_VERSION,&scratch[110],pi->unit);
0442 printk(" at 0x%x, mode %d (%s), delay %d\n",pi->port,
0443 pi->mode,mode_string[pi->mode],pi->delay);
0444 }
0445
0446 static struct pi_protocol bpck = {
0447 .owner = THIS_MODULE,
0448 .name = "bpck",
0449 .max_mode = 5,
0450 .epp_first = 2,
0451 .default_delay = 4,
0452 .max_units = 255,
0453 .write_regr = bpck_write_regr,
0454 .read_regr = bpck_read_regr,
0455 .write_block = bpck_write_block,
0456 .read_block = bpck_read_block,
0457 .connect = bpck_connect,
0458 .disconnect = bpck_disconnect,
0459 .test_port = bpck_test_port,
0460 .probe_unit = bpck_probe_unit,
0461 .test_proto = bpck_test_proto,
0462 .log_adapter = bpck_log_adapter,
0463 };
0464
0465 static int __init bpck_init(void)
0466 {
0467 return paride_register(&bpck);
0468 }
0469
0470 static void __exit bpck_exit(void)
0471 {
0472 paride_unregister(&bpck);
0473 }
0474
0475 MODULE_LICENSE("GPL");
0476 module_init(bpck_init)
0477 module_exit(bpck_exit)