linux/drivers/block/paride/aten.c
<<
>>
Prefs
   1/* 
   2        aten.c  (c) 1997-8  Grant R. Guenther <grant@torque.net>
   3                            Under the terms of the GNU General Public License.
   4
   5        aten.c is a low-level protocol driver for the ATEN EH-100
   6        parallel port adapter.  The EH-100 supports 4-bit and 8-bit
   7        modes only.  There is also an EH-132 which supports EPP mode
   8        transfers.  The EH-132 is not yet supported.
   9
  10*/
  11
  12/* Changes:
  13
  14        1.01    GRG 1998.05.05  init_proto, release_proto
  15
  16*/
  17
  18#define ATEN_VERSION      "1.01"
  19
  20#include <linux/module.h>
  21#include <linux/init.h>
  22#include <linux/delay.h>
  23#include <linux/kernel.h>
  24#include <linux/wait.h>
  25#include <linux/types.h>
  26#include <asm/io.h>
  27
  28#include "paride.h"
  29
  30#define j44(a,b)                ((((a>>4)&0x0f)|(b&0xf0))^0x88)
  31
  32/* cont = 0 - access the IDE register file 
  33   cont = 1 - access the IDE command set 
  34*/
  35
  36static int  cont_map[2] = { 0x08, 0x20 };
  37
  38static void  aten_write_regr( PIA *pi, int cont, int regr, int val)
  39
  40{       int r;
  41
  42        r = regr + cont_map[cont] + 0x80;
  43
  44        w0(r); w2(0xe); w2(6); w0(val); w2(7); w2(6); w2(0xc);
  45}
  46
  47static int aten_read_regr( PIA *pi, int cont, int regr )
  48
  49{       int  a, b, r;
  50
  51        r = regr + cont_map[cont] + 0x40;
  52
  53        switch (pi->mode) {
  54
  55        case 0: w0(r); w2(0xe); w2(6); 
  56                w2(7); w2(6); w2(0);
  57                a = r1(); w0(0x10); b = r1(); w2(0xc);
  58                return j44(a,b);
  59
  60        case 1: r |= 0x10;
  61                w0(r); w2(0xe); w2(6); w0(0xff); 
  62                w2(0x27); w2(0x26); w2(0x20);
  63                a = r0();
  64                w2(0x26); w2(0xc);
  65                return a;
  66        }
  67        return -1;
  68}
  69
  70static void aten_read_block( PIA *pi, char * buf, int count )
  71
  72{       int  k, a, b, c, d;
  73
  74        switch (pi->mode) {
  75
  76        case 0: w0(0x48); w2(0xe); w2(6);
  77                for (k=0;k<count/2;k++) {
  78                        w2(7); w2(6); w2(2);
  79                        a = r1(); w0(0x58); b = r1();
  80                        w2(0); d = r1(); w0(0x48); c = r1();
  81                        buf[2*k] = j44(c,d);
  82                        buf[2*k+1] = j44(a,b);
  83                }
  84                w2(0xc);
  85                break;
  86
  87        case 1: w0(0x58); w2(0xe); w2(6);
  88                for (k=0;k<count/2;k++) {
  89                        w2(0x27); w2(0x26); w2(0x22);
  90                        a = r0(); w2(0x20); b = r0();
  91                        buf[2*k] = b; buf[2*k+1] = a;
  92                }
  93                w2(0x26); w2(0xc);
  94                break;
  95        }
  96}
  97
  98static void aten_write_block( PIA *pi, char * buf, int count )
  99
 100{       int k;
 101
 102        w0(0x88); w2(0xe); w2(6);
 103        for (k=0;k<count/2;k++) {
 104                w0(buf[2*k+1]); w2(0xe); w2(6);
 105                w0(buf[2*k]); w2(7); w2(6);
 106        }
 107        w2(0xc);
 108}
 109
 110static void aten_connect ( PIA *pi  )
 111
 112{       pi->saved_r0 = r0();
 113        pi->saved_r2 = r2();
 114        w2(0xc);        
 115}
 116
 117static void aten_disconnect ( PIA *pi )
 118
 119{       w0(pi->saved_r0);
 120        w2(pi->saved_r2);
 121} 
 122
 123static void aten_log_adapter( PIA *pi, char * scratch, int verbose )
 124
 125{       char    *mode_string[2] = {"4-bit","8-bit"};
 126
 127        printk("%s: aten %s, ATEN EH-100 at 0x%x, ",
 128                pi->device,ATEN_VERSION,pi->port);
 129        printk("mode %d (%s), delay %d\n",pi->mode,
 130                mode_string[pi->mode],pi->delay);
 131
 132}
 133
 134static struct pi_protocol aten = {
 135        .owner          = THIS_MODULE,
 136        .name           = "aten",
 137        .max_mode       = 2,
 138        .epp_first      = 2,
 139        .default_delay  = 1,
 140        .max_units      = 1,
 141        .write_regr     = aten_write_regr,
 142        .read_regr      = aten_read_regr,
 143        .write_block    = aten_write_block,
 144        .read_block     = aten_read_block,
 145        .connect        = aten_connect,
 146        .disconnect     = aten_disconnect,
 147        .log_adapter    = aten_log_adapter,
 148};
 149
 150static int __init aten_init(void)
 151{
 152        return paride_register(&aten);
 153}
 154
 155static void __exit aten_exit(void)
 156{
 157        paride_unregister( &aten );
 158}
 159
 160MODULE_LICENSE("GPL");
 161module_init(aten_init)
 162module_exit(aten_exit)
 163