PageRenderTime 32ms CodeModel.GetById 13ms app.highlight 15ms RepoModel.GetById 2ms app.codeStats 0ms

/drivers/block/paride/epia.c

https://bitbucket.org/evzijst/gittest
C | 316 lines | 219 code | 65 blank | 32 comment | 38 complexity | fc70494574c76104db19c3a379ea0c1a MD5 | raw file
  1/* 
  2        epia.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  3                              Under the terms of the GNU General Public License.
  4
  5        epia.c is a low-level protocol driver for Shuttle Technologies 
  6	EPIA parallel to IDE adapter chip.  This device is now obsolete
  7	and has been replaced with the EPAT chip, which is supported
  8	by epat.c, however, some devices based on EPIA are still
  9	available.
 10
 11*/
 12
 13/* Changes:
 14
 15        1.01    GRG 1998.05.06 init_proto, release_proto
 16	1.02    GRG 1998.06.17 support older versions of EPIA
 17
 18*/
 19
 20#define EPIA_VERSION      "1.02"
 21
 22#include <linux/module.h>
 23#include <linux/init.h>
 24#include <linux/delay.h>
 25#include <linux/kernel.h>
 26#include <linux/types.h>
 27#include <linux/wait.h>
 28#include <asm/io.h>
 29
 30#include "paride.h"
 31
 32/* mode codes:  0  nybble reads on port 1, 8-bit writes
 33                1  5/3 reads on ports 1 & 2, 8-bit writes
 34                2  8-bit reads and writes
 35                3  8-bit EPP mode
 36		4  16-bit EPP
 37		5  32-bit EPP
 38*/
 39
 40#define j44(a,b)                (((a>>4)&0x0f)+(b&0xf0))
 41#define j53(a,b)                (((a>>3)&0x1f)+((b<<4)&0xe0))
 42
 43/* cont =  0   IDE register file
 44   cont =  1   IDE control registers
 45*/
 46
 47static int cont_map[2] = { 0, 0x80 };
 48
 49static int epia_read_regr( PIA *pi, int cont, int regr )
 50
 51{       int     a, b, r;
 52
 53	regr += cont_map[cont];
 54
 55        switch (pi->mode)  {
 56
 57        case 0: r = regr^0x39;
 58                w0(r); w2(1); w2(3); w0(r);
 59                a = r1(); w2(1); b = r1(); w2(4);
 60                return j44(a,b);
 61
 62        case 1: r = regr^0x31;
 63                w0(r); w2(1); w0(r&0x37); 
 64                w2(3); w2(5); w0(r|0xf0);
 65                a = r1(); b = r2(); w2(4);
 66                return j53(a,b);
 67
 68        case 2: r = regr^0x29;
 69                w0(r); w2(1); w2(0X21); w2(0x23); 
 70                a = r0(); w2(4);
 71                return a;
 72
 73	case 3:
 74	case 4:
 75        case 5: w3(regr); w2(0x24); a = r4(); w2(4);
 76                return a;
 77
 78        }
 79        return -1;
 80}       
 81
 82static void epia_write_regr( PIA *pi, int cont, int regr, int val)
 83
 84{       int  r;
 85
 86	regr += cont_map[cont];
 87
 88        switch (pi->mode)  {
 89
 90        case 0:
 91        case 1:
 92        case 2: r = regr^0x19;
 93                w0(r); w2(1); w0(val); w2(3); w2(4);
 94                break;
 95
 96	case 3:
 97	case 4:
 98        case 5: r = regr^0x40;
 99                w3(r); w4(val); w2(4);
100                break;
101        }
102}
103
104#define WR(r,v)         epia_write_regr(pi,0,r,v)
105#define RR(r)           (epia_read_regr(pi,0,r))
106
107/* The use of register 0x84 is entirely unclear - it seems to control
108   some EPP counters ...  currently we know about 3 different block
109   sizes:  the standard 512 byte reads and writes, 12 byte writes and 
110   2048 byte reads (the last two being used in the CDrom drivers.
111*/
112
113static void epia_connect ( PIA *pi  )
114
115{       pi->saved_r0 = r0();
116        pi->saved_r2 = r2();
117
118        w2(4); w0(0xa0); w0(0x50); w0(0xc0); w0(0x30); w0(0xa0); w0(0);
119        w2(1); w2(4);
120        if (pi->mode >= 3) { 
121                w0(0xa); w2(1); w2(4); w0(0x82); w2(4); w2(0xc); w2(4);
122                w2(0x24); w2(0x26); w2(4);
123        }
124        WR(0x86,8);  
125}
126
127static void epia_disconnect ( PIA *pi )
128
129{       /* WR(0x84,0x10); */
130        w0(pi->saved_r0);
131        w2(1); w2(4);
132        w0(pi->saved_r0);
133        w2(pi->saved_r2);
134} 
135
136static void epia_read_block( PIA *pi, char * buf, int count )
137
138{       int     k, ph, a, b;
139
140        switch (pi->mode) {
141
142        case 0: w0(0x81); w2(1); w2(3); w0(0xc1);
143                ph = 1;
144                for (k=0;k<count;k++) {
145                        w2(2+ph); a = r1();
146                        w2(4+ph); b = r1();
147                        buf[k] = j44(a,b);
148                        ph = 1 - ph;
149                } 
150                w0(0); w2(4);
151                break;
152
153        case 1: w0(0x91); w2(1); w0(0x10); w2(3); 
154                w0(0x51); w2(5); w0(0xd1); 
155                ph = 1;
156                for (k=0;k<count;k++) {
157                        w2(4+ph);
158                        a = r1(); b = r2();
159                        buf[k] = j53(a,b);
160                        ph = 1 - ph;
161                }
162                w0(0); w2(4);
163                break;
164
165        case 2: w0(0x89); w2(1); w2(0x23); w2(0x21); 
166                ph = 1;
167                for (k=0;k<count;k++) {
168                        w2(0x24+ph);
169                        buf[k] = r0();
170                        ph = 1 - ph;
171                }
172                w2(6); w2(4);
173                break;
174
175        case 3: if (count > 512) WR(0x84,3);
176		w3(0); w2(0x24);
177                for (k=0;k<count;k++) buf[k] = r4();
178                w2(4); WR(0x84,0);
179                break;
180
181        case 4: if (count > 512) WR(0x84,3);
182		w3(0); w2(0x24);
183		for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
184                w2(4); WR(0x84,0);
185                break;
186
187        case 5: if (count > 512) WR(0x84,3);
188		w3(0); w2(0x24);
189                for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
190                w2(4); WR(0x84,0);
191                break;
192
193        }
194}
195
196static void epia_write_block( PIA *pi, char * buf, int count )
197
198{       int     ph, k, last, d;
199
200        switch (pi->mode) {
201
202        case 0:
203        case 1:
204        case 2: w0(0xa1); w2(1); w2(3); w2(1); w2(5);
205                ph = 0;  last = 0x8000;
206                for (k=0;k<count;k++) {
207                        d = buf[k];
208                        if (d != last) { last = d; w0(d); }
209                        w2(4+ph);
210                        ph = 1 - ph;
211                }
212                w2(7); w2(4);
213                break;
214
215        case 3: if (count < 512) WR(0x84,1);
216		w3(0x40);
217                for (k=0;k<count;k++) w4(buf[k]);
218		if (count < 512) WR(0x84,0);
219                break;
220
221        case 4: if (count < 512) WR(0x84,1);
222		w3(0x40);
223                for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
224		if (count < 512) WR(0x84,0);
225                break;
226
227        case 5: if (count < 512) WR(0x84,1);
228		w3(0x40);
229                for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
230		if (count < 512) WR(0x84,0);
231                break;
232
233        }
234
235}
236
237static int epia_test_proto( PIA *pi, char * scratch, int verbose )
238
239{       int     j, k, f;
240	int	e[2] = {0,0};
241
242        epia_connect(pi);
243        for (j=0;j<2;j++) {
244            WR(6,0xa0+j*0x10);
245            for (k=0;k<256;k++) {
246                WR(2,k^0xaa);
247                WR(3,k^0x55);
248                if (RR(2) != (k^0xaa)) e[j]++;
249                }
250	    WR(2,1); WR(3,1);
251            }
252        epia_disconnect(pi);
253
254        f = 0;
255        epia_connect(pi);
256        WR(0x84,8);
257        epia_read_block(pi,scratch,512);
258        for (k=0;k<256;k++) {
259            if ((scratch[2*k] & 0xff) != ((k+1) & 0xff)) f++;
260            if ((scratch[2*k+1] & 0xff) != ((-2-k) & 0xff)) f++;
261        }
262        WR(0x84,0);
263        epia_disconnect(pi);
264
265        if (verbose)  {
266            printk("%s: epia: port 0x%x, mode %d, test=(%d,%d,%d)\n",
267                   pi->device,pi->port,pi->mode,e[0],e[1],f);
268        }
269        
270        return (e[0] && e[1]) || f;
271
272}
273
274
275static void epia_log_adapter( PIA *pi, char * scratch, int verbose )
276
277{       char    *mode_string[6] = {"4-bit","5/3","8-bit",
278				   "EPP-8","EPP-16","EPP-32"};
279
280        printk("%s: epia %s, Shuttle EPIA at 0x%x, ",
281                pi->device,EPIA_VERSION,pi->port);
282        printk("mode %d (%s), delay %d\n",pi->mode,
283		mode_string[pi->mode],pi->delay);
284
285}
286
287static struct pi_protocol epia = {
288	.owner		= THIS_MODULE,
289	.name		= "epia",
290	.max_mode	= 6,
291	.epp_first	= 3,
292	.default_delay	= 1,
293	.max_units	= 1,
294	.write_regr	= epia_write_regr,
295	.read_regr	= epia_read_regr,
296	.write_block	= epia_write_block,
297	.read_block	= epia_read_block,
298	.connect	= epia_connect,
299	.disconnect	= epia_disconnect,
300	.test_proto	= epia_test_proto,
301	.log_adapter	= epia_log_adapter,
302};
303
304static int __init epia_init(void)
305{
306	return pi_register(&epia)-1;
307}
308
309static void __exit epia_exit(void)
310{
311	pi_unregister(&epia);
312}
313
314MODULE_LICENSE("GPL");
315module_init(epia_init)
316module_exit(epia_exit)