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