on26.c
上传用户:ajay2009
上传日期:2009-05-22
资源大小:495k
文件大小:7k
源码类别:

驱动编程

开发平台:

Unix_Linux

  1. /* 
  2.         on26.c    (c) 1997-8  Grant R. Guenther <grant@torque.net>
  3.                               Under the terms of the GNU General Public License.
  4.         on26.c is a low-level protocol driver for the 
  5.         OnSpec 90c26 parallel to IDE adapter chip.
  6. */
  7. /* Changes:
  8.         1.01    GRG 1998.05.06 init_proto, release_proto
  9. 1.02    GRG 1998.09.23 updates for the -E rev chip
  10. 1.03    GRG 1998.12.14 fix for slave drives
  11. 1.04    GRG 1998.12.20 yet another bug fix
  12. */
  13. #define ON26_VERSION      "1.04"
  14. #include <linux/module.h>
  15. #include <linux/init.h>
  16. #include <linux/delay.h>
  17. #include <linux/kernel.h>
  18. #include <linux/types.h>
  19. #include <linux/wait.h>
  20. #include <asm/io.h>
  21. #include "paride.h"
  22. /* mode codes:  0  nybble reads, 8-bit writes
  23.                 1  8-bit reads and writes
  24.                 2  8-bit EPP mode
  25. 3  EPP-16
  26. 4  EPP-32
  27. */
  28. #define j44(a,b)  (((a>>4)&0x0f)|(b&0xf0))
  29. #define P1 w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
  30. #define P2 w2(5);w2(7);w2(5);w2(4);
  31. /* cont = 0 - access the IDE register file 
  32.    cont = 1 - access the IDE command set 
  33. */
  34. static int on26_read_regr( PIA *pi, int cont, int regr )
  35. {       int     a, b, r;
  36. r = (regr<<2) + 1 + cont;
  37.         switch (pi->mode)  {
  38.         case 0: w0(1); P1; w0(r); P2; w0(0); P1; 
  39. w2(6); a = r1(); w2(4);
  40. w2(6); b = r1(); w2(4);
  41. w2(6); w2(4); w2(6); w2(4);
  42.                 return j44(a,b);
  43.         case 1: w0(1); P1; w0(r); P2; w0(0); P1;
  44. w2(0x26); a = r0(); w2(4); w2(0x26); w2(4);
  45.                 return a;
  46. case 2:
  47. case 3:
  48.         case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
  49. w3(0); w3(0); w2(0x24); a = r4(); w2(4);
  50. w2(0x24); r4(); w2(4);
  51.                 return a;
  52.         }
  53.         return -1;
  54. }       
  55. static void on26_write_regr( PIA *pi, int cont, int regr, int val )
  56. {       int  r;
  57.         r = (regr<<2) + 1 + cont;
  58.         switch (pi->mode)  {
  59.         case 0:
  60.         case 1: w0(1); P1; w0(r); P2; w0(0); P1;
  61. w0(val); P2; w0(val); P2;
  62. break;
  63. case 2:
  64. case 3:
  65.         case 4: w3(1); w3(1); w2(5); w4(r); w2(4);
  66. w3(0); w3(0); 
  67. w2(5); w4(val); w2(4);
  68. w2(5); w4(val); w2(4);
  69.                 break;
  70.         }
  71. }
  72. #define  CCP(x)  w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff);
  73.  w0(0x87);w0(0x78);w0(x);w2(4);w2(5);w2(4);w0(0xff);
  74. static void on26_connect ( PIA *pi )
  75. {       int x;
  76. pi->saved_r0 = r0();
  77.         pi->saved_r2 = r2();
  78.         CCP(0x20);
  79. x = 8; if (pi->mode) x = 9;
  80. w0(2); P1; w0(8); P2;
  81. w0(2); P1; w0(x); P2;
  82. }
  83. static void on26_disconnect ( PIA *pi )
  84. {       if (pi->mode >= 2) { w3(4); w3(4); w3(4); w3(4); }
  85.               else { w0(4); P1; w0(4); P1; }
  86. CCP(0x30);
  87.         w0(pi->saved_r0);
  88.         w2(pi->saved_r2);
  89. #define RESET_WAIT  200
  90. static int on26_test_port( PIA *pi)  /* hard reset */
  91. {       int     i, m, d, x=0, y=0;
  92.         pi->saved_r0 = r0();
  93.         pi->saved_r2 = r2();
  94.         d = pi->delay;
  95.         m = pi->mode;
  96.         pi->delay = 5;
  97.         pi->mode = 0;
  98.         w2(0xc);
  99.         CCP(0x30); CCP(0); 
  100.         w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff);
  101.         i = ((r1() & 0xf0) << 4); w0(0x87);
  102.         i |= (r1() & 0xf0); w0(0x78);
  103.         w0(0x20);w2(4);w2(5);
  104.         i |= ((r1() & 0xf0) >> 4);
  105.         w2(4);w0(0xff);
  106.         if (i == 0xb5f) {
  107.             w0(2); P1; w0(0);   P2;
  108.             w0(3); P1; w0(0);   P2;
  109.             w0(2); P1; w0(8);   P2; udelay(100);
  110.             w0(2); P1; w0(0xa); P2; udelay(100);
  111.             w0(2); P1; w0(8);   P2; udelay(1000);
  112.             
  113.             on26_write_regr(pi,0,6,0xa0);
  114.             for (i=0;i<RESET_WAIT;i++) {
  115.                 on26_write_regr(pi,0,6,0xa0);
  116.                 x = on26_read_regr(pi,0,7);
  117.                 on26_write_regr(pi,0,6,0xb0);
  118.                 y = on26_read_regr(pi,0,7);
  119.                 if (!((x&0x80)||(y&0x80))) break;
  120.                 mdelay(100);
  121.             }
  122.     if (i == RESET_WAIT) 
  123. printk("on26: Device reset failed (%x,%x)n",x,y);
  124.             w0(4); P1; w0(4); P1;
  125.         }
  126.         CCP(0x30);
  127.         pi->delay = d;
  128.         pi->mode = m;
  129.         w0(pi->saved_r0);
  130.         w2(pi->saved_r2);
  131.         return 5;
  132. }
  133. static void on26_read_block( PIA *pi, char * buf, int count )
  134. {       int     k, a, b;
  135.         switch (pi->mode) {
  136.         case 0: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x18); P2; w0(0); P1;
  137. udelay(10);
  138. for (k=0;k<count;k++) {
  139.                         w2(6); a = r1();
  140.                         w2(4); b = r1();
  141.                         buf[k] = j44(a,b);
  142.                 }
  143. w0(2); P1; w0(8); P2; 
  144.                 break;
  145.         case 1: w0(1); P1; w0(1); P2; w0(2); P1; w0(0x19); P2; w0(0); P1;
  146. udelay(10);
  147.                 for (k=0;k<count/2;k++) {
  148.                         w2(0x26); buf[2*k] = r0();  
  149. w2(0x24); buf[2*k+1] = r0();
  150.                 }
  151.                 w0(2); P1; w0(9); P2;
  152.                 break;
  153.         case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
  154. w3(0); w3(0); w2(0x24);
  155. udelay(10);
  156.                 for (k=0;k<count;k++) buf[k] = r4();
  157.                 w2(4);
  158.                 break;
  159.         case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
  160.                 w3(0); w3(0); w2(0x24);
  161.                 udelay(10);
  162.                 for (k=0;k<count/2;k++) ((u16 *)buf)[k] = r4w();
  163.                 w2(4);
  164.                 break;
  165.         case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
  166.                 w3(0); w3(0); w2(0x24);
  167.                 udelay(10);
  168.                 for (k=0;k<count/4;k++) ((u32 *)buf)[k] = r4l();
  169.                 w2(4);
  170.                 break;
  171.         }
  172. }
  173. static void on26_write_block( PIA *pi, char * buf, int count )
  174. {       int k;
  175.         switch (pi->mode) {
  176.         case 0: 
  177.         case 1: w0(1); P1; w0(1); P2; 
  178. w0(2); P1; w0(0x18+pi->mode); P2; w0(0); P1;
  179. udelay(10);
  180. for (k=0;k<count/2;k++) {
  181.                         w2(5); w0(buf[2*k]); 
  182. w2(7); w0(buf[2*k+1]);
  183.                 }
  184.                 w2(5); w2(4);
  185. w0(2); P1; w0(8+pi->mode); P2;
  186.                 break;
  187.         case 2: w3(1); w3(1); w2(5); w4(1); w2(4);
  188. w3(0); w3(0); w2(0xc5);
  189. udelay(10);
  190.                 for (k=0;k<count;k++) w4(buf[k]);
  191. w2(0xc4);
  192.                 break;
  193.         case 3: w3(1); w3(1); w2(5); w4(1); w2(4);
  194.                 w3(0); w3(0); w2(0xc5);
  195.                 udelay(10);
  196.                 for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
  197.                 w2(0xc4);
  198.                 break;
  199.         case 4: w3(1); w3(1); w2(5); w4(1); w2(4);
  200.                 w3(0); w3(0); w2(0xc5);
  201.                 udelay(10);
  202.                 for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
  203.                 w2(0xc4);
  204.                 break;
  205.         }
  206. }
  207. static void on26_log_adapter( PIA *pi, char * scratch, int verbose )
  208. {       char    *mode_string[5] = {"4-bit","8-bit","EPP-8",
  209.    "EPP-16","EPP-32"};
  210.         printk("%s: on26 %s, OnSpec 90c26 at 0x%x, ",
  211.                 pi->device,ON26_VERSION,pi->port);
  212.         printk("mode %d (%s), delay %dn",pi->mode,
  213. mode_string[pi->mode],pi->delay);
  214. }
  215. static struct pi_protocol on26 = {
  216. .owner = THIS_MODULE,
  217. .name = "on26",
  218. .max_mode = 5,
  219. .epp_first = 2,
  220. .default_delay = 1,
  221. .max_units = 1,
  222. .write_regr = on26_write_regr,
  223. .read_regr = on26_read_regr,
  224. .write_block = on26_write_block,
  225. .read_block = on26_read_block,
  226. .connect = on26_connect,
  227. .disconnect = on26_disconnect,
  228. .test_port = on26_test_port,
  229. .log_adapter = on26_log_adapter,
  230. };
  231. static int __init on26_init(void)
  232. {
  233. return pi_register(&on26)-1;
  234. }
  235. static void __exit on26_exit(void)
  236. {
  237. pi_unregister(&on26);
  238. }
  239. MODULE_LICENSE("GPL");
  240. module_init(on26_init)
  241. module_exit(on26_exit)