fit3.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. fit3.c (c) 1998 Grant R. Guenther <grant@torque.net>
  3. Under the terms of the GNU General Public License.
  4. fit3.c is a low-level protocol driver for newer models
  5. of the Fidelity International Technology parallel port adapter.
  6. This adapter is used in their TransDisk 3000 portable
  7. hard-drives, as well as CD-ROM, PD-CD and other devices.
  8. The TD-2000 and certain older devices use a different protocol.
  9. Try the fit2 protocol module with them.
  10. NB: The FIT adapters do not appear to support the control
  11. registers. So, we map ALT_STATUS to STATUS and NO-OP writes
  12. to the device control register - this means that IDE reset
  13. will not work on these devices.
  14. */
  15. #define FIT3_VERSION "1.0"
  16. #include <linux/module.h>
  17. #include <linux/init.h>
  18. #include <linux/delay.h>
  19. #include <linux/kernel.h>
  20. #include <linux/types.h>
  21. #include <linux/wait.h>
  22. #include <asm/io.h>
  23. #include "paride.h"
  24. #define j44(a,b) (((a>>3)&0x0f)|((b<<1)&0xf0))
  25. #define w7(byte) {out_p(7,byte);}
  26. #define r7() (in_p(7) & 0xff)
  27. /* cont = 0 - access the IDE register file
  28. cont = 1 - access the IDE command set
  29. */
  30. static void fit3_write_regr( PIA *pi, int cont, int regr, int val)
  31. { if (cont == 1) return;
  32. switch (pi->mode) {
  33. case 0:
  34. case 1: w2(0xc); w0(regr); w2(0x8); w2(0xc);
  35. w0(val); w2(0xd);
  36. w0(0); w2(0xc);
  37. break;
  38. case 2: w2(0xc); w0(regr); w2(0x8); w2(0xc);
  39. w4(val); w4(0);
  40. w2(0xc);
  41. break;
  42. }
  43. }
  44. static int fit3_read_regr( PIA *pi, int cont, int regr )
  45. { int a, b;
  46. if (cont) {
  47. if (regr != 6) return 0xff;
  48. regr = 7;
  49. }
  50. switch (pi->mode) {
  51. case 0: w2(0xc); w0(regr + 0x10); w2(0x8); w2(0xc);
  52. w2(0xd); a = r1();
  53. w2(0xf); b = r1();
  54. w2(0xc);
  55. return j44(a,b);
  56. case 1: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
  57. w2(0xec); w2(0xee); w2(0xef); a = r0();
  58. w2(0xc);
  59. return a;
  60. case 2: w2(0xc); w0(regr + 0x90); w2(0x8); w2(0xc);
  61. w2(0xec);
  62. a = r4(); b = r4();
  63. w2(0xc);
  64. return a;
  65. }
  66. return -1;
  67. }
  68. static void fit3_read_block( PIA *pi, char * buf, int count )
  69. { int k, a, b, c, d;
  70. switch (pi->mode) {
  71. case 0: w2(0xc); w0(0x10); w2(0x8); w2(0xc);
  72. for (k=0;k<count/2;k++) {
  73. w2(0xd); a = r1();
  74. w2(0xf); b = r1();
  75. w2(0xc); c = r1();
  76. w2(0xe); d = r1();
  77. buf[2*k ] = j44(a,b);
  78. buf[2*k+1] = j44(c,d);
  79. }
  80. w2(0xc);
  81. break;
  82. case 1: w2(0xc); w0(0x90); w2(0x8); w2(0xc);
  83. w2(0xec); w2(0xee);
  84. for (k=0;k<count/2;k++) {
  85. w2(0xef); a = r0();
  86. w2(0xee); b = r0();
  87. buf[2*k ] = a;
  88. buf[2*k+1] = b;
  89. }
  90. w2(0xec);
  91. w2(0xc);
  92. break;
  93. case 2: w2(0xc); w0(0x90); w2(0x8); w2(0xc);
  94. w2(0xec);
  95. for (k=0;k<count;k++) buf[k] = r4();
  96. w2(0xc);
  97. break;
  98. }
  99. }
  100. static void fit3_write_block( PIA *pi, char * buf, int count )
  101. { int k;
  102. switch (pi->mode) {
  103. case 0:
  104. case 1: w2(0xc); w0(0); w2(0x8); w2(0xc);
  105. for (k=0;k<count/2;k++) {
  106. w0(buf[2*k ]); w2(0xd);
  107. w0(buf[2*k+1]); w2(0xc);
  108. }
  109. break;
  110. case 2: w2(0xc); w0(0); w2(0x8); w2(0xc);
  111. for (k=0;k<count;k++) w4(buf[k]);
  112. w2(0xc);
  113. break;
  114. }
  115. }
  116. static void fit3_connect ( PIA *pi )
  117. { pi->saved_r0 = r0();
  118. pi->saved_r2 = r2();
  119. w2(0xc); w0(0); w2(0xa);
  120. if (pi->mode == 2) {
  121. w2(0xc); w0(0x9); w2(0x8); w2(0xc);
  122. }
  123. }
  124. static void fit3_disconnect ( PIA *pi )
  125. { w2(0xc); w0(0xa); w2(0x8); w2(0xc);
  126. w0(pi->saved_r0);
  127. w2(pi->saved_r2);
  128. }
  129. static void fit3_log_adapter( PIA *pi, char * scratch, int verbose )
  130. { char *mode_string[3] = {"4-bit","8-bit","EPP"};
  131. printk("%s: fit3 %s, FIT 3000 adapter at 0x%x, "
  132. "mode %d (%s), delay %d\n",
  133. pi->device,FIT3_VERSION,pi->port,
  134. pi->mode,mode_string[pi->mode],pi->delay);
  135. }
  136. static struct pi_protocol fit3 = {
  137. .owner = THIS_MODULE,
  138. .name = "fit3",
  139. .max_mode = 3,
  140. .epp_first = 2,
  141. .default_delay = 1,
  142. .max_units = 1,
  143. .write_regr = fit3_write_regr,
  144. .read_regr = fit3_read_regr,
  145. .write_block = fit3_write_block,
  146. .read_block = fit3_read_block,
  147. .connect = fit3_connect,
  148. .disconnect = fit3_disconnect,
  149. .log_adapter = fit3_log_adapter,
  150. };
  151. static int __init fit3_init(void)
  152. {
  153. return paride_register(&fit3);
  154. }
  155. static void __exit fit3_exit(void)
  156. {
  157. paride_unregister(&fit3);
  158. }
  159. MODULE_LICENSE("GPL");
  160. module_init(fit3_init)
  161. module_exit(fit3_exit)