1 /* 2 backpack.c (c) 2001 Micro Solutions Inc. 3 Released under the terms of the GNU General Public license 4 5 backpack.c is a low-level protocol driver for the Micro Solutions 6 "BACKPACK" parallel port IDE adapter 7 (Works on Series 6 drives) 8 9 Written by: Ken Hahn (linux-dev@micro-solutions.com) 10 Clive Turvey (linux-dev@micro-solutions.com) 11 12 */ 13 14 #include <linux/module.h> 15 #include <linux/init.h> 16 #include <linux/kernel.h> 17 #include <linux/types.h> 18 #include <linux/parport.h> 19 #include "pata_parport.h" 20 21 /* 60772 Commands */ 22 #define ACCESS_REG 0x00 23 #define ACCESS_PORT 0x40 24 25 #define ACCESS_READ 0x00 26 #define ACCESS_WRITE 0x20 27 28 /* 60772 Command Prefix */ 29 #define CMD_PREFIX_SET 0xe0 // Special command that modifies next command's operation 30 #define CMD_PREFIX_RESET 0xc0 // Resets current cmd modifier reg bits 31 #define PREFIX_IO16 0x01 // perform 16-bit wide I/O 32 #define PREFIX_FASTWR 0x04 // enable PPC mode fast-write 33 #define PREFIX_BLK 0x08 // enable block transfer mode 34 35 /* 60772 Registers */ 36 #define REG_STATUS 0x00 // status register 37 #define STATUS_IRQA 0x01 // Peripheral IRQA line 38 #define STATUS_EEPROM_DO 0x40 // Serial EEPROM data bit 39 #define REG_VERSION 0x01 // PPC version register (read) 40 #define REG_HWCFG 0x02 // Hardware Config register 41 #define REG_RAMSIZE 0x03 // Size of RAM Buffer 42 #define RAMSIZE_128K 0x02 43 #define REG_EEPROM 0x06 // EEPROM control register 44 #define EEPROM_SK 0x01 // eeprom SK bit 45 #define EEPROM_DI 0x02 // eeprom DI bit 46 #define EEPROM_CS 0x04 // eeprom CS bit 47 #define EEPROM_EN 0x08 // eeprom output enable 48 #define REG_BLKSIZE 0x08 // Block transfer len (24 bit) 49 50 /* flags */ 51 #define fifo_wait 0x10 52 53 /* DONT CHANGE THESE LEST YOU BREAK EVERYTHING - BIT FIELD DEPENDENCIES */ 54 #define PPCMODE_UNI_SW 0 55 #define PPCMODE_UNI_FW 1 56 #define PPCMODE_BI_SW 2 57 #define PPCMODE_BI_FW 3 58 #define PPCMODE_EPP_BYTE 4 59 #define PPCMODE_EPP_WORD 5 60 #define PPCMODE_EPP_DWORD 6 61 62 int mode_map[] = { PPCMODE_UNI_FW, PPCMODE_BI_FW, PPCMODE_EPP_BYTE, 63 PPCMODE_EPP_WORD, PPCMODE_EPP_DWORD }; 64 65 static void bpck6_send_cmd(struct pi_adapter *pi, u8 cmd) 66 { 67 switch (mode_map[pi->mode]) { 68 case PPCMODE_UNI_SW: 69 case PPCMODE_UNI_FW: 70 case PPCMODE_BI_SW: 71 case PPCMODE_BI_FW: 72 parport_write_data(pi->pardev->port, cmd); 73 parport_frob_control(pi->pardev->port, 0, PARPORT_CONTROL_AUTOFD); 74 break; 75 case PPCMODE_EPP_BYTE: 76 case PPCMODE_EPP_WORD: 77 case PPCMODE_EPP_DWORD: 78 pi->pardev->port->ops->epp_write_addr(pi->pardev->port, &cmd, 1, 0); 79 break; 80 } 81 } 82 83 static u8 bpck6_rd_data_byte(struct pi_adapter *pi) 84 { 85 u8 data = 0; 86 87 switch (mode_map[pi->mode]) { 88 case PPCMODE_UNI_SW: 89 case PPCMODE_UNI_FW: 90 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_STROBE, 91 PARPORT_CONTROL_INIT); 92 data = parport_read_status(pi->pardev->port); 93 data = ((data & 0x80) >> 1) | ((data & 0x38) >> 3); 94 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_STROBE, 95 PARPORT_CONTROL_STROBE); 96 data |= parport_read_status(pi->pardev->port) & 0xB8; 97 break; 98 case PPCMODE_BI_SW: 99 case PPCMODE_BI_FW: 100 parport_data_reverse(pi->pardev->port); 101 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_STROBE, 102 PARPORT_CONTROL_STROBE | PARPORT_CONTROL_INIT); 103 data = parport_read_data(pi->pardev->port); 104 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_STROBE, 0); 105 parport_data_forward(pi->pardev->port); 106 break; 107 case PPCMODE_EPP_BYTE: 108 case PPCMODE_EPP_WORD: 109 case PPCMODE_EPP_DWORD: 110 pi->pardev->port->ops->epp_read_data(pi->pardev->port, &data, 1, 0); 111 break; 112 } 113 114 return data; 115 } 116 117 static void bpck6_wr_data_byte(struct pi_adapter *pi, u8 data) 118 { 119 switch (mode_map[pi->mode]) { 120 case PPCMODE_UNI_SW: 121 case PPCMODE_UNI_FW: 122 case PPCMODE_BI_SW: 123 case PPCMODE_BI_FW: 124 parport_write_data(pi->pardev->port, data); 125 parport_frob_control(pi->pardev->port, 0, PARPORT_CONTROL_INIT); 126 break; 127 case PPCMODE_EPP_BYTE: 128 case PPCMODE_EPP_WORD: 129 case PPCMODE_EPP_DWORD: 130 pi->pardev->port->ops->epp_write_data(pi->pardev->port, &data, 1, 0); 131 break; 132 } 133 } 134 135 static int bpck6_read_regr(struct pi_adapter *pi, int cont, int reg) 136 { 137 u8 port = cont ? reg | 8 : reg; 138 139 bpck6_send_cmd(pi, port | ACCESS_PORT | ACCESS_READ); 140 return bpck6_rd_data_byte(pi); 141 } 142 143 static void bpck6_write_regr(struct pi_adapter *pi, int cont, int reg, int val) 144 { 145 u8 port = cont ? reg | 8 : reg; 146 147 bpck6_send_cmd(pi, port | ACCESS_PORT | ACCESS_WRITE); 148 bpck6_wr_data_byte(pi, val); 149 } 150 151 static void bpck6_wait_for_fifo(struct pi_adapter *pi) 152 { 153 int i; 154 155 if (pi->private & fifo_wait) { 156 for (i = 0; i < 20; i++) 157 parport_read_status(pi->pardev->port); 158 } 159 } 160 161 static void bpck6_write_block(struct pi_adapter *pi, char *buf, int len) 162 { 163 u8 this, last; 164 165 bpck6_send_cmd(pi, REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE); 166 bpck6_wr_data_byte(pi, (u8)len); 167 bpck6_wr_data_byte(pi, (u8)(len >> 8)); 168 bpck6_wr_data_byte(pi, 0); 169 170 bpck6_send_cmd(pi, CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK); 171 bpck6_send_cmd(pi, ATA_REG_DATA | ACCESS_PORT | ACCESS_WRITE); 172 173 switch (mode_map[pi->mode]) { 174 case PPCMODE_UNI_SW: 175 case PPCMODE_BI_SW: 176 while (len--) { 177 parport_write_data(pi->pardev->port, *buf++); 178 parport_frob_control(pi->pardev->port, 0, 179 PARPORT_CONTROL_INIT); 180 } 181 break; 182 case PPCMODE_UNI_FW: 183 case PPCMODE_BI_FW: 184 bpck6_send_cmd(pi, CMD_PREFIX_SET | PREFIX_FASTWR); 185 186 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_STROBE, 187 PARPORT_CONTROL_STROBE); 188 189 last = *buf; 190 191 parport_write_data(pi->pardev->port, last); 192 193 while (len) { 194 this = *buf++; 195 len--; 196 197 if (this == last) { 198 parport_frob_control(pi->pardev->port, 0, 199 PARPORT_CONTROL_INIT); 200 } else { 201 parport_write_data(pi->pardev->port, this); 202 last = this; 203 } 204 } 205 206 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_STROBE, 207 0); 208 bpck6_send_cmd(pi, CMD_PREFIX_RESET | PREFIX_FASTWR); 209 break; 210 case PPCMODE_EPP_BYTE: 211 pi->pardev->port->ops->epp_write_data(pi->pardev->port, buf, 212 len, PARPORT_EPP_FAST_8); 213 bpck6_wait_for_fifo(pi); 214 break; 215 case PPCMODE_EPP_WORD: 216 pi->pardev->port->ops->epp_write_data(pi->pardev->port, buf, 217 len, PARPORT_EPP_FAST_16); 218 bpck6_wait_for_fifo(pi); 219 break; 220 case PPCMODE_EPP_DWORD: 221 pi->pardev->port->ops->epp_write_data(pi->pardev->port, buf, 222 len, PARPORT_EPP_FAST_32); 223 bpck6_wait_for_fifo(pi); 224 break; 225 } 226 227 bpck6_send_cmd(pi, CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK); 228 } 229 230 static void bpck6_read_block(struct pi_adapter *pi, char *buf, int len) 231 { 232 bpck6_send_cmd(pi, REG_BLKSIZE | ACCESS_REG | ACCESS_WRITE); 233 bpck6_wr_data_byte(pi, (u8)len); 234 bpck6_wr_data_byte(pi, (u8)(len >> 8)); 235 bpck6_wr_data_byte(pi, 0); 236 237 bpck6_send_cmd(pi, CMD_PREFIX_SET | PREFIX_IO16 | PREFIX_BLK); 238 bpck6_send_cmd(pi, ATA_REG_DATA | ACCESS_PORT | ACCESS_READ); 239 240 switch (mode_map[pi->mode]) { 241 case PPCMODE_UNI_SW: 242 case PPCMODE_UNI_FW: 243 while (len) { 244 u8 d; 245 246 parport_frob_control(pi->pardev->port, 247 PARPORT_CONTROL_STROBE, 248 PARPORT_CONTROL_INIT); /* DATA STROBE */ 249 d = parport_read_status(pi->pardev->port); 250 d = ((d & 0x80) >> 1) | ((d & 0x38) >> 3); 251 parport_frob_control(pi->pardev->port, 252 PARPORT_CONTROL_STROBE, 253 PARPORT_CONTROL_STROBE); 254 d |= parport_read_status(pi->pardev->port) & 0xB8; 255 *buf++ = d; 256 len--; 257 } 258 break; 259 case PPCMODE_BI_SW: 260 case PPCMODE_BI_FW: 261 parport_data_reverse(pi->pardev->port); 262 while (len) { 263 parport_frob_control(pi->pardev->port, 264 PARPORT_CONTROL_STROBE, 265 PARPORT_CONTROL_STROBE | PARPORT_CONTROL_INIT); 266 *buf++ = parport_read_data(pi->pardev->port); 267 len--; 268 } 269 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_STROBE, 270 0); 271 parport_data_forward(pi->pardev->port); 272 break; 273 case PPCMODE_EPP_BYTE: 274 pi->pardev->port->ops->epp_read_data(pi->pardev->port, buf, len, 275 PARPORT_EPP_FAST_8); 276 break; 277 case PPCMODE_EPP_WORD: 278 pi->pardev->port->ops->epp_read_data(pi->pardev->port, buf, len, 279 PARPORT_EPP_FAST_16); 280 break; 281 case PPCMODE_EPP_DWORD: 282 pi->pardev->port->ops->epp_read_data(pi->pardev->port, buf, len, 283 PARPORT_EPP_FAST_32); 284 break; 285 } 286 287 bpck6_send_cmd(pi, CMD_PREFIX_RESET | PREFIX_IO16 | PREFIX_BLK); 288 } 289 290 static int bpck6_open(struct pi_adapter *pi) 291 { 292 u8 i, j, k; 293 294 pi->saved_r0 = parport_read_data(pi->pardev->port); 295 pi->saved_r2 = parport_read_control(pi->pardev->port) & 0x5F; 296 297 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT, 298 PARPORT_CONTROL_SELECT); 299 if (pi->saved_r0 == 'b') 300 parport_write_data(pi->pardev->port, 'x'); 301 parport_write_data(pi->pardev->port, 'b'); 302 parport_write_data(pi->pardev->port, 'p'); 303 parport_write_data(pi->pardev->port, pi->unit); 304 parport_write_data(pi->pardev->port, ~pi->unit); 305 306 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT, 0); 307 parport_write_control(pi->pardev->port, PARPORT_CONTROL_INIT); 308 309 i = mode_map[pi->mode] & 0x0C; 310 if (i == 0) 311 i = (mode_map[pi->mode] & 2) | 1; 312 parport_write_data(pi->pardev->port, i); 313 314 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT, 315 PARPORT_CONTROL_SELECT); 316 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_AUTOFD, 317 PARPORT_CONTROL_AUTOFD); 318 319 j = ((i & 0x08) << 4) | ((i & 0x07) << 3); 320 k = parport_read_status(pi->pardev->port) & 0xB8; 321 if (j != k) 322 goto fail; 323 324 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_AUTOFD, 0); 325 k = (parport_read_status(pi->pardev->port) & 0xB8) ^ 0xB8; 326 if (j != k) 327 goto fail; 328 329 if (i & 4) // EPP 330 parport_frob_control(pi->pardev->port, 331 PARPORT_CONTROL_SELECT | PARPORT_CONTROL_INIT, 0); 332 else // PPC/ECP 333 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT, 0); 334 335 pi->private = 0; 336 337 bpck6_send_cmd(pi, ACCESS_REG | ACCESS_WRITE | REG_RAMSIZE); 338 bpck6_wr_data_byte(pi, RAMSIZE_128K); 339 340 bpck6_send_cmd(pi, ACCESS_REG | ACCESS_READ | REG_VERSION); 341 if ((bpck6_rd_data_byte(pi) & 0x3F) == 0x0C) 342 pi->private |= fifo_wait; 343 344 return 1; 345 346 fail: 347 parport_write_control(pi->pardev->port, pi->saved_r2); 348 parport_write_data(pi->pardev->port, pi->saved_r0); 349 350 return 0; // FAIL 351 } 352 353 static void bpck6_deselect(struct pi_adapter *pi) 354 { 355 if (mode_map[pi->mode] & 4) // EPP 356 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_INIT, 357 PARPORT_CONTROL_INIT); 358 else // PPC/ECP 359 parport_frob_control(pi->pardev->port, PARPORT_CONTROL_SELECT, 360 PARPORT_CONTROL_SELECT); 361 362 parport_write_data(pi->pardev->port, pi->saved_r0); 363 parport_write_control(pi->pardev->port, 364 pi->saved_r2 | PARPORT_CONTROL_SELECT); 365 parport_write_control(pi->pardev->port, pi->saved_r2); 366 } 367 368 static void bpck6_wr_extout(struct pi_adapter *pi, u8 regdata) 369 { 370 bpck6_send_cmd(pi, REG_VERSION | ACCESS_REG | ACCESS_WRITE); 371 bpck6_wr_data_byte(pi, (u8)((regdata & 0x03) << 6)); 372 } 373 374 static void bpck6_connect(struct pi_adapter *pi) 375 { 376 dev_dbg(&pi->dev, "connect\n"); 377 378 bpck6_open(pi); 379 bpck6_wr_extout(pi, 0x3); 380 } 381 382 static void bpck6_disconnect(struct pi_adapter *pi) 383 { 384 dev_dbg(&pi->dev, "disconnect\n"); 385 bpck6_wr_extout(pi, 0x0); 386 bpck6_deselect(pi); 387 } 388 389 static int bpck6_test_port(struct pi_adapter *pi) /* check for 8-bit port */ 390 { 391 dev_dbg(&pi->dev, "PARPORT indicates modes=%x for lp=0x%lx\n", 392 pi->pardev->port->modes, pi->pardev->port->base); 393 394 /* look at the parport device to see what modes we can use */ 395 if (pi->pardev->port->modes & PARPORT_MODE_EPP) 396 return 5; /* Can do EPP */ 397 if (pi->pardev->port->modes & PARPORT_MODE_TRISTATE) 398 return 2; 399 return 1; /* Just flat SPP */ 400 } 401 402 static int bpck6_probe_unit(struct pi_adapter *pi) 403 { 404 int out, saved_mode; 405 406 dev_dbg(&pi->dev, "PROBE UNIT %x on port:%x\n", pi->unit, pi->port); 407 408 saved_mode = pi->mode; 409 /*LOWER DOWN TO UNIDIRECTIONAL*/ 410 pi->mode = 0; 411 412 out = bpck6_open(pi); 413 414 dev_dbg(&pi->dev, "ppc_open returned %2x\n", out); 415 416 if(out) 417 { 418 bpck6_deselect(pi); 419 dev_dbg(&pi->dev, "leaving probe\n"); 420 pi->mode = saved_mode; 421 return(1); 422 } 423 else 424 { 425 dev_dbg(&pi->dev, "Failed open\n"); 426 pi->mode = saved_mode; 427 return(0); 428 } 429 } 430 431 static void bpck6_log_adapter(struct pi_adapter *pi) 432 { 433 char *mode_string[5]= 434 {"4-bit","8-bit","EPP-8","EPP-16","EPP-32"}; 435 436 dev_info(&pi->dev, "Micro Solutions BACKPACK Drive unit %d at 0x%x, mode:%d (%s), delay %d\n", 437 pi->unit, pi->port, pi->mode, mode_string[pi->mode], pi->delay); 438 } 439 440 static struct pi_protocol bpck6 = { 441 .owner = THIS_MODULE, 442 .name = "bpck6", 443 .max_mode = 5, 444 .epp_first = 2, /* 2-5 use epp (need 8 ports) */ 445 .max_units = 255, 446 .write_regr = bpck6_write_regr, 447 .read_regr = bpck6_read_regr, 448 .write_block = bpck6_write_block, 449 .read_block = bpck6_read_block, 450 .connect = bpck6_connect, 451 .disconnect = bpck6_disconnect, 452 .test_port = bpck6_test_port, 453 .probe_unit = bpck6_probe_unit, 454 .log_adapter = bpck6_log_adapter, 455 }; 456 457 MODULE_LICENSE("GPL"); 458 MODULE_AUTHOR("Micro Solutions Inc."); 459 MODULE_DESCRIPTION("BACKPACK Protocol module, compatible with PARIDE"); 460 module_pata_parport_driver(bpck6); 461