309 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * (c) 1997-1998 Grant R. Guenther <grant@torque.net>4 *5 * This is a low-level driver for the KBIC-951A and KBIC-971A6 * parallel to IDE adapter chips from KingByte Information Systems.7 *8 * The chips are almost identical, however, the wakeup code9 * required for the 971A interferes with the correct operation of10 * the 951A, so this driver registers itself twice, once for11 * each chip.12 */13 14#include <linux/module.h>15#include <linux/init.h>16#include <linux/delay.h>17#include <linux/kernel.h>18#include <linux/types.h>19#include <linux/wait.h>20#include <asm/io.h>21#include "pata_parport.h"22 23#define r12w() (delay_p, inw(pi->port + 1) & 0xffff)24 25#define j44(a, b) ((((a >> 4) & 0x0f) | (b & 0xf0)) ^ 0x88)26#define j53(w) (((w >> 3) & 0x1f) | ((w >> 4) & 0xe0))27 28 29/*30 * cont = 0 - access the IDE register file31 * cont = 1 - access the IDE command set32 */33static int cont_map[2] = { 0x80, 0x40 };34 35static int kbic_read_regr(struct pi_adapter *pi, int cont, int regr)36{37 int a, b, s;38 39 s = cont_map[cont];40 41 switch (pi->mode) {42 case 0:43 w0(regr | 0x18 | s); w2(4); w2(6); w2(4); w2(1); w0(8);44 a = r1(); w0(0x28); b = r1(); w2(4);45 return j44(a, b);46 case 1:47 w0(regr|0x38 | s); w2(4); w2(6); w2(4); w2(5); w0(8);48 a = r12w(); w2(4);49 return j53(a);50 case 2:51 w0(regr | 0x08 | s); w2(4); w2(6); w2(4); w2(0xa5); w2(0xa1);52 a = r0(); w2(4);53 return a;54 case 3:55 case 4:56 case 5:57 w0(0x20 | s); w2(4); w2(6); w2(4); w3(regr);58 a = r4(); b = r4(); w2(4); w2(0); w2(4);59 return a;60 }61 62 return -1;63}64 65static void kbic_write_regr(struct pi_adapter *pi, int cont, int regr, int val)66{67 int s = cont_map[cont];68 69 switch (pi->mode) {70 case 0:71 case 1:72 case 2:73 w0(regr | 0x10 | s); w2(4); w2(6); w2(4);74 w0(val); w2(5); w2(4);75 break;76 case 3:77 case 4:78 case 5:79 w0(0x20 | s); w2(4); w2(6); w2(4); w3(regr);80 w4(val); w4(val);81 w2(4); w2(0); w2(4);82 break;83 }84}85 86static void k951_connect(struct pi_adapter *pi)87{88 pi->saved_r0 = r0();89 pi->saved_r2 = r2();90 w2(4);91}92 93static void k951_disconnect(struct pi_adapter *pi)94{95 w0(pi->saved_r0);96 w2(pi->saved_r2);97}98 99#define CCP(x) \100 do { \101 w2(0xc4); w0(0xaa); w0(0x55); \102 w0(0); w0(0xff); w0(0x87); \103 w0(0x78); w0(x); w2(0xc5); \104 w2(0xc4); w0(0xff); \105 } while (0)106 107static void k971_connect(struct pi_adapter *pi)108{109 pi->saved_r0 = r0();110 pi->saved_r2 = r2();111 CCP(0x20);112 w2(4);113}114 115static void k971_disconnect(struct pi_adapter *pi)116{117 CCP(0x30);118 w0(pi->saved_r0);119 w2(pi->saved_r2);120}121 122/*123 * count must be congruent to 0 MOD 4, but all known applications124 *have this property.125 */126static void kbic_read_block(struct pi_adapter *pi, char *buf, int count)127{128 int k, a, b;129 130 switch (pi->mode) {131 case 0:132 w0(0x98); w2(4); w2(6); w2(4);133 for (k = 0; k < count / 2; k++) {134 w2(1); w0(8);135 a = r1();136 w0(0x28);137 b = r1();138 buf[2 * k] = j44(a, b);139 w2(5);140 b = r1();141 w0(8);142 a = r1();143 buf[2 * k + 1] = j44(a, b);144 w2(4);145 }146 break;147 case 1:148 w0(0xb8); w2(4); w2(6); w2(4);149 for (k = 0; k < count / 4; k++) {150 w0(0xb8);151 w2(4); w2(5);152 w0(8);153 buf[4 * k] = j53(r12w());154 w0(0xb8);155 buf[4 * k + 1] = j53(r12w());156 w2(4); w2(5);157 buf[4 * k + 3] = j53(r12w());158 w0(8);159 buf[4 * k + 2] = j53(r12w());160 }161 w2(4);162 break;163 case 2:164 w0(0x88); w2(4); w2(6); w2(4);165 for (k = 0; k < count / 2; k++) {166 w2(0xa0); w2(0xa1);167 buf[2 * k] = r0();168 w2(0xa5);169 buf[2 * k + 1] = r0();170 }171 w2(4);172 break;173 case 3:174 w0(0xa0); w2(4); w2(6); w2(4); w3(0);175 for (k = 0; k < count; k++)176 buf[k] = r4();177 w2(4); w2(0); w2(4);178 break;179 case 4:180 w0(0xa0); w2(4); w2(6); w2(4); w3(0);181 for (k = 0; k < count / 2; k++)182 ((u16 *)buf)[k] = r4w();183 w2(4); w2(0); w2(4);184 break;185 case 5:186 w0(0xa0); w2(4); w2(6); w2(4); w3(0);187 for (k = 0; k < count / 4; k++)188 ((u32 *)buf)[k] = r4l();189 w2(4); w2(0); w2(4);190 break;191 }192}193 194static void kbic_write_block(struct pi_adapter *pi, char *buf, int count)195{196 int k;197 198 switch (pi->mode) {199 case 0:200 case 1:201 case 2:202 w0(0x90); w2(4); w2(6); w2(4);203 for (k = 0; k < count / 2; k++) {204 w0(buf[2 * k + 1]);205 w2(0); w2(4);206 w0(buf[2 * k]);207 w2(5); w2(4);208 }209 break;210 case 3:211 w0(0xa0); w2(4); w2(6); w2(4); w3(0);212 for (k = 0; k < count / 2; k++) {213 w4(buf[2 * k + 1]);214 w4(buf[2 * k]);215 }216 w2(4); w2(0); w2(4);217 break;218 case 4:219 w0(0xa0); w2(4); w2(6); w2(4); w3(0);220 for (k = 0; k < count / 2; k++)221 w4w(swab16(((u16 *)buf)[k]));222 w2(4); w2(0); w2(4);223 break;224 case 5:225 w0(0xa0); w2(4); w2(6); w2(4); w3(0);226 for (k = 0; k < count / 4; k++)227 w4l(swab16(((u16 *)buf)[2 * k]) |228 swab16(((u16 *)buf)[2 * k + 1]) << 16);229 w2(4); w2(0); w2(4);230 break;231 }232}233 234static void kbic_log_adapter(struct pi_adapter *pi, char *chip)235{236 char *mode[6] = { "4-bit", "5/3", "8-bit", "EPP-8", "EPP_16", "EPP-32"};237 238 dev_info(&pi->dev, "KingByte %s at 0x%x, mode %d (%s), delay %d\n",239 chip, pi->port, pi->mode, mode[pi->mode], pi->delay);240}241 242static void k951_log_adapter(struct pi_adapter *pi)243{244 kbic_log_adapter(pi, "KBIC-951A");245}246 247static void k971_log_adapter(struct pi_adapter *pi)248{249 kbic_log_adapter(pi, "KBIC-971A");250}251 252static struct pi_protocol k951 = {253 .owner = THIS_MODULE,254 .name = "k951",255 .max_mode = 6,256 .epp_first = 3,257 .default_delay = 1,258 .max_units = 1,259 .write_regr = kbic_write_regr,260 .read_regr = kbic_read_regr,261 .write_block = kbic_write_block,262 .read_block = kbic_read_block,263 .connect = k951_connect,264 .disconnect = k951_disconnect,265 .log_adapter = k951_log_adapter,266};267 268static struct pi_protocol k971 = {269 .owner = THIS_MODULE,270 .name = "k971",271 .max_mode = 6,272 .epp_first = 3,273 .default_delay = 1,274 .max_units = 1,275 .write_regr = kbic_write_regr,276 .read_regr = kbic_read_regr,277 .write_block = kbic_write_block,278 .read_block = kbic_read_block,279 .connect = k971_connect,280 .disconnect = k971_disconnect,281 .log_adapter = k971_log_adapter,282};283 284static int __init kbic_init(void)285{286 int rv;287 288 rv = pata_parport_register_driver(&k951);289 if (rv < 0)290 return rv;291 rv = pata_parport_register_driver(&k971);292 if (rv < 0)293 pata_parport_unregister_driver(&k951);294 return rv;295}296 297static void __exit kbic_exit(void)298{299 pata_parport_unregister_driver(&k951);300 pata_parport_unregister_driver(&k971);301}302 303MODULE_LICENSE("GPL");304MODULE_AUTHOR("Grant R. Guenther <grant@torque.net>");305MODULE_DESCRIPTION("KingByte Information Systems KBIC-951A and KBIC-971A "306 "parallel port IDE adapter protocol driver");307module_init(kbic_init)308module_exit(kbic_exit)309