on26.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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); (void)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. }
  90. #define RESET_WAIT 200
  91. static int on26_test_port( PIA *pi) /* hard reset */
  92. { int i, m, d, x=0, y=0;
  93. pi->saved_r0 = r0();
  94. pi->saved_r2 = r2();
  95. d = pi->delay;
  96. m = pi->mode;
  97. pi->delay = 5;
  98. pi->mode = 0;
  99. w2(0xc);
  100. CCP(0x30); CCP(0);
  101. w0(0xfe);w0(0xaa);w0(0x55);w0(0);w0(0xff);
  102. i = ((r1() & 0xf0) << 4); w0(0x87);
  103. i |= (r1() & 0xf0); w0(0x78);
  104. w0(0x20);w2(4);w2(5);
  105. i |= ((r1() & 0xf0) >> 4);
  106. w2(4);w0(0xff);
  107. if (i == 0xb5f) {
  108. w0(2); P1; w0(0); P2;
  109. w0(3); P1; w0(0); P2;
  110. w0(2); P1; w0(8); P2; udelay(100);
  111. w0(2); P1; w0(0xa); P2; udelay(100);
  112. w0(2); P1; w0(8); P2; udelay(1000);
  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 %d\n",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 paride_register(&on26);
  234. }
  235. static void __exit on26_exit(void)
  236. {
  237. paride_unregister(&on26);
  238. }
  239. MODULE_LICENSE("GPL");
  240. module_init(on26_init)
  241. module_exit(on26_exit)