162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * (c) 1998 Grant R. Guenther <grant@torque.net> 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * ktti.c is a low-level protocol driver for the KT Technology 662306a36Sopenharmony_ci * parallel port adapter. This adapter is used in the "PHd" 762306a36Sopenharmony_ci * portable hard-drives. As far as I can tell, this device 862306a36Sopenharmony_ci * supports 4-bit mode _only_. 962306a36Sopenharmony_ci*/ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/module.h> 1262306a36Sopenharmony_ci#include <linux/init.h> 1362306a36Sopenharmony_ci#include <linux/delay.h> 1462306a36Sopenharmony_ci#include <linux/kernel.h> 1562306a36Sopenharmony_ci#include <linux/types.h> 1662306a36Sopenharmony_ci#include <linux/wait.h> 1762306a36Sopenharmony_ci#include <asm/io.h> 1862306a36Sopenharmony_ci#include "pata_parport.h" 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#define j44(a, b) (((a >> 4) & 0x0f) | (b & 0xf0)) 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci/* 2362306a36Sopenharmony_ci * cont = 0 - access the IDE register file 2462306a36Sopenharmony_ci * cont = 1 - access the IDE command set 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_cistatic int cont_map[2] = { 0x10, 0x08 }; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistatic void ktti_write_regr(struct pi_adapter *pi, int cont, int regr, int val) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci int r = regr + cont_map[cont]; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci w0(r); w2(0xb); w2(0xa); w2(3); w2(6); 3362306a36Sopenharmony_ci w0(val); w2(3); w0(0); w2(6); w2(0xb); 3462306a36Sopenharmony_ci} 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistatic int ktti_read_regr(struct pi_adapter *pi, int cont, int regr) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci int a, b, r; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci r = regr + cont_map[cont]; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci w0(r); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9); 4362306a36Sopenharmony_ci a = r1(); w2(0xc); b = r1(); w2(9); w2(0xc); w2(9); 4462306a36Sopenharmony_ci return j44(a, b); 4562306a36Sopenharmony_ci} 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistatic void ktti_read_block(struct pi_adapter *pi, char *buf, int count) 4862306a36Sopenharmony_ci{ 4962306a36Sopenharmony_ci int k, a, b; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci for (k = 0; k < count / 2; k++) { 5262306a36Sopenharmony_ci w0(0x10); w2(0xb); w2(0xa); w2(9); w2(0xc); w2(9); 5362306a36Sopenharmony_ci a = r1(); w2(0xc); b = r1(); w2(9); 5462306a36Sopenharmony_ci buf[2*k] = j44(a, b); 5562306a36Sopenharmony_ci a = r1(); w2(0xc); b = r1(); w2(9); 5662306a36Sopenharmony_ci buf[2*k+1] = j44(a, b); 5762306a36Sopenharmony_ci } 5862306a36Sopenharmony_ci} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic void ktti_write_block(struct pi_adapter *pi, char *buf, int count) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci int k; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci for (k = 0; k < count / 2; k++) { 6562306a36Sopenharmony_ci w0(0x10); w2(0xb); w2(0xa); w2(3); w2(6); 6662306a36Sopenharmony_ci w0(buf[2 * k]); w2(3); 6762306a36Sopenharmony_ci w0(buf[2 * k + 1]); w2(6); 6862306a36Sopenharmony_ci w2(0xb); 6962306a36Sopenharmony_ci } 7062306a36Sopenharmony_ci} 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistatic void ktti_connect(struct pi_adapter *pi) 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci pi->saved_r0 = r0(); 7562306a36Sopenharmony_ci pi->saved_r2 = r2(); 7662306a36Sopenharmony_ci w2(0xb); w2(0xa); w0(0); w2(3); w2(6); 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic void ktti_disconnect(struct pi_adapter *pi) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci w2(0xb); w2(0xa); w0(0xa0); w2(3); w2(4); 8262306a36Sopenharmony_ci w0(pi->saved_r0); 8362306a36Sopenharmony_ci w2(pi->saved_r2); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cistatic void ktti_log_adapter(struct pi_adapter *pi) 8762306a36Sopenharmony_ci{ 8862306a36Sopenharmony_ci dev_info(&pi->dev, "KT adapter at 0x%x, delay %d\n", 8962306a36Sopenharmony_ci pi->port, pi->delay); 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cistatic struct pi_protocol ktti = { 9362306a36Sopenharmony_ci .owner = THIS_MODULE, 9462306a36Sopenharmony_ci .name = "ktti", 9562306a36Sopenharmony_ci .max_mode = 1, 9662306a36Sopenharmony_ci .epp_first = 2, 9762306a36Sopenharmony_ci .default_delay = 1, 9862306a36Sopenharmony_ci .max_units = 1, 9962306a36Sopenharmony_ci .write_regr = ktti_write_regr, 10062306a36Sopenharmony_ci .read_regr = ktti_read_regr, 10162306a36Sopenharmony_ci .write_block = ktti_write_block, 10262306a36Sopenharmony_ci .read_block = ktti_read_block, 10362306a36Sopenharmony_ci .connect = ktti_connect, 10462306a36Sopenharmony_ci .disconnect = ktti_disconnect, 10562306a36Sopenharmony_ci .log_adapter = ktti_log_adapter, 10662306a36Sopenharmony_ci}; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 10962306a36Sopenharmony_ciMODULE_AUTHOR("Grant R. Guenther <grant@torque.net>"); 11062306a36Sopenharmony_ciMODULE_DESCRIPTION("KT Technology parallel port IDE adapter protocol driver"); 11162306a36Sopenharmony_cimodule_pata_parport_driver(ktti); 112