18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci on20.c (c) 1996-8 Grant R. Guenther <grant@torque.net> 38c2ecf20Sopenharmony_ci Under the terms of the GNU General Public License. 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci on20.c is a low-level protocol driver for the 68c2ecf20Sopenharmony_ci Onspec 90c20 parallel to IDE adapter. 78c2ecf20Sopenharmony_ci*/ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci/* Changes: 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci 1.01 GRG 1998.05.06 init_proto, release_proto 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci*/ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define ON20_VERSION "1.01" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#include <linux/module.h> 188c2ecf20Sopenharmony_ci#include <linux/init.h> 198c2ecf20Sopenharmony_ci#include <linux/delay.h> 208c2ecf20Sopenharmony_ci#include <linux/kernel.h> 218c2ecf20Sopenharmony_ci#include <linux/types.h> 228c2ecf20Sopenharmony_ci#include <linux/wait.h> 238c2ecf20Sopenharmony_ci#include <asm/io.h> 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#include "paride.h" 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci#define op(f) w2(4);w0(f);w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4); 288c2ecf20Sopenharmony_ci#define vl(v) w2(4);w0(v);w2(5);w2(7);w2(5);w2(4); 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci#define j44(a,b) (((a>>4)&0x0f)|(b&0xf0)) 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci/* cont = 0 - access the IDE register file 338c2ecf20Sopenharmony_ci cont = 1 - access the IDE command set 348c2ecf20Sopenharmony_ci*/ 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic int on20_read_regr( PIA *pi, int cont, int regr ) 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci{ int h,l, r ; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci r = (regr<<2) + 1 + cont; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci op(1); vl(r); op(0); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci switch (pi->mode) { 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci case 0: w2(4); w2(6); l = r1(); 478c2ecf20Sopenharmony_ci w2(4); w2(6); h = r1(); 488c2ecf20Sopenharmony_ci w2(4); w2(6); w2(4); w2(6); w2(4); 498c2ecf20Sopenharmony_ci return j44(l,h); 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci case 1: w2(4); w2(0x26); r = r0(); 528c2ecf20Sopenharmony_ci w2(4); w2(0x26); w2(4); 538c2ecf20Sopenharmony_ci return r; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci } 568c2ecf20Sopenharmony_ci return -1; 578c2ecf20Sopenharmony_ci} 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic void on20_write_regr( PIA *pi, int cont, int regr, int val ) 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci{ int r; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci r = (regr<<2) + 1 + cont; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci op(1); vl(r); 668c2ecf20Sopenharmony_ci op(0); vl(val); 678c2ecf20Sopenharmony_ci op(0); vl(val); 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic void on20_connect ( PIA *pi) 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci{ pi->saved_r0 = r0(); 738c2ecf20Sopenharmony_ci pi->saved_r2 = r2(); 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci w2(4);w0(0);w2(0xc);w2(4);w2(6);w2(4);w2(6);w2(4); 768c2ecf20Sopenharmony_ci if (pi->mode) { op(2); vl(8); op(2); vl(9); } 778c2ecf20Sopenharmony_ci else { op(2); vl(0); op(2); vl(8); } 788c2ecf20Sopenharmony_ci} 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cistatic void on20_disconnect ( PIA *pi ) 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci{ w2(4);w0(7);w2(4);w2(0xc);w2(4); 838c2ecf20Sopenharmony_ci w0(pi->saved_r0); 848c2ecf20Sopenharmony_ci w2(pi->saved_r2); 858c2ecf20Sopenharmony_ci} 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_cistatic void on20_read_block( PIA *pi, char * buf, int count ) 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci{ int k, l, h; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci op(1); vl(1); op(0); 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci for (k=0;k<count;k++) 948c2ecf20Sopenharmony_ci if (pi->mode) { 958c2ecf20Sopenharmony_ci w2(4); w2(0x26); buf[k] = r0(); 968c2ecf20Sopenharmony_ci } else { 978c2ecf20Sopenharmony_ci w2(6); l = r1(); w2(4); 988c2ecf20Sopenharmony_ci w2(6); h = r1(); w2(4); 998c2ecf20Sopenharmony_ci buf[k] = j44(l,h); 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci w2(4); 1028c2ecf20Sopenharmony_ci} 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_cistatic void on20_write_block( PIA *pi, char * buf, int count ) 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci{ int k; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci op(1); vl(1); op(0); 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci for (k=0;k<count;k++) { w2(5); w0(buf[k]); w2(7); } 1118c2ecf20Sopenharmony_ci w2(4); 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_cistatic void on20_log_adapter( PIA *pi, char * scratch, int verbose ) 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci{ char *mode_string[2] = {"4-bit","8-bit"}; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci printk("%s: on20 %s, OnSpec 90c20 at 0x%x, ", 1198c2ecf20Sopenharmony_ci pi->device,ON20_VERSION,pi->port); 1208c2ecf20Sopenharmony_ci printk("mode %d (%s), delay %d\n",pi->mode, 1218c2ecf20Sopenharmony_ci mode_string[pi->mode],pi->delay); 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci} 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_cistatic struct pi_protocol on20 = { 1268c2ecf20Sopenharmony_ci .owner = THIS_MODULE, 1278c2ecf20Sopenharmony_ci .name = "on20", 1288c2ecf20Sopenharmony_ci .max_mode = 2, 1298c2ecf20Sopenharmony_ci .epp_first = 2, 1308c2ecf20Sopenharmony_ci .default_delay = 1, 1318c2ecf20Sopenharmony_ci .max_units = 1, 1328c2ecf20Sopenharmony_ci .write_regr = on20_write_regr, 1338c2ecf20Sopenharmony_ci .read_regr = on20_read_regr, 1348c2ecf20Sopenharmony_ci .write_block = on20_write_block, 1358c2ecf20Sopenharmony_ci .read_block = on20_read_block, 1368c2ecf20Sopenharmony_ci .connect = on20_connect, 1378c2ecf20Sopenharmony_ci .disconnect = on20_disconnect, 1388c2ecf20Sopenharmony_ci .log_adapter = on20_log_adapter, 1398c2ecf20Sopenharmony_ci}; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_cistatic int __init on20_init(void) 1428c2ecf20Sopenharmony_ci{ 1438c2ecf20Sopenharmony_ci return paride_register(&on20); 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic void __exit on20_exit(void) 1478c2ecf20Sopenharmony_ci{ 1488c2ecf20Sopenharmony_ci paride_unregister(&on20); 1498c2ecf20Sopenharmony_ci} 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 1528c2ecf20Sopenharmony_cimodule_init(on20_init) 1538c2ecf20Sopenharmony_cimodule_exit(on20_exit) 154