1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * (c) 1998 Grant R. Guenther <grant@torque.net> 4 * 5 * ktti.c is a low-level protocol driver for the KT Technology 6 * parallel port adapter. This adapter is used in the "PHd" 7 * portable hard-drives. As far as I can tell, this device 8 * supports 4-bit mode _only_. 9 */ 10 11 #include <linux/module.h> 12 #include <linux/init.h> 13 #include <linux/delay.h> 14 #include <linux/kernel.h> 15 #include <linux/types.h> 16 #include <linux/wait.h> 17 #include <asm/io.h> 18 #include "pata_parport.h" 19 20 #define j44(a, b) (((a >> 4) & 0x0f) | (b & 0xf0)) 21 22 /* 23 * cont = 0 - access the IDE register file 24 * cont = 1 - access the IDE command set 25 */ 26 static int cont_map[2] = { 0x10, 0x08 }; 27 28 static void ktti_write_regr(struct pi_adapter *pi, int cont, int regr, int val) 29 { 30 int r = regr + cont_map[cont]; 31 32 w0(r); w2(0xb); w2(0xa); w2(3); w2(6); 33 w0(val); w2(3); w0(0); w2(6); w2(0xb); 34 } 35 36 static int ktti_read_regr(struct pi_adapter *pi, int cont, int regr) 37 { 38 int a, b, r; 39 40 r = regr + cont_map[cont]; 41 42 w0(r); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9); 43 a = r1(); w2(0xc); b = r1(); w2(9); w2(0xc); w2(9); 44 return j44(a, b); 45 } 46 47 static void ktti_read_block(struct pi_adapter *pi, char *buf, int count) 48 { 49 int k, a, b; 50 51 for (k = 0; k < count / 2; k++) { 52 w0(0x10); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9); 53 a = r1(); w2(0xc); b = r1(); w2(9); 54 buf[2*k] = j44(a, b); 55 a = r1(); w2(0xc); b = r1(); w2(9); 56 buf[2*k+1] = j44(a, b); 57 } 58 } 59 60 static void ktti_write_block(struct pi_adapter *pi, char *buf, int count) 61 { 62 int k; 63 64 for (k = 0; k < count / 2; k++) { 65 w0(0x10); w2(0xb); w2(0xa); w2(3); w2(6); 66 w0(buf[2 * k]); w2(3); 67 w0(buf[2 * k + 1]); w2(6); 68 w2(0xb); 69 } 70 } 71 72 static void ktti_connect(struct pi_adapter *pi) 73 { 74 pi->saved_r0 = r0(); 75 pi->saved_r2 = r2(); 76 w2(0xb); w2(0xa); w0(0); w2(3); w2(6); 77 } 78 79 static void ktti_disconnect(struct pi_adapter *pi) 80 { 81 w2(0xb); w2(0xa); w0(0xa0); w2(3); w2(4); 82 w0(pi->saved_r0); 83 w2(pi->saved_r2); 84 } 85 86 static void ktti_log_adapter(struct pi_adapter *pi) 87 { 88 dev_info(&pi->dev, "KT adapter at 0x%x, delay %d\n", 89 pi->port, pi->delay); 90 } 91 92 static struct pi_protocol ktti = { 93 .owner = THIS_MODULE, 94 .name = "ktti", 95 .max_mode = 1, 96 .epp_first = 2, 97 .default_delay = 1, 98 .max_units = 1, 99 .write_regr = ktti_write_regr, 100 .read_regr = ktti_read_regr, 101 .write_block = ktti_write_block, 102 .read_block = ktti_read_block, 103 .connect = ktti_connect, 104 .disconnect = ktti_disconnect, 105 .log_adapter = ktti_log_adapter, 106 }; 107 108 MODULE_LICENSE("GPL"); 109 module_pata_parport_driver(ktti); 110