on20.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*
  2. on20.c (c) 1996-8 Grant R. Guenther <grant@torque.net>
  3. Under the terms of the GNU General Public License.
  4. on20.c is a low-level protocol driver for the
  5. Onspec 90c20 parallel to IDE adapter.
  6. */
  7. /* Changes:
  8. 1.01 GRG 1998.05.06 init_proto, release_proto
  9. */
  10. #define ON20_VERSION "1.01"
  11. #include <linux/module.h>
  12. #include <linux/init.h>
  13. #include <linux/delay.h>
  14. #include <linux/kernel.h>
  15. #include <linux/types.h>
  16. #include <linux/wait.h>
  17. #include <asm/io.h>
  18. #include "paride.h"
  19. #define op(f) w2(4);w0(f);w2(5);w2(0xd);w2(5);w2(0xd);w2(5);w2(4);
  20. #define vl(v) w2(4);w0(v);w2(5);w2(7);w2(5);w2(4);
  21. #define j44(a,b) (((a>>4)&0x0f)|(b&0xf0))
  22. /* cont = 0 - access the IDE register file
  23. cont = 1 - access the IDE command set
  24. */
  25. static int on20_read_regr( PIA *pi, int cont, int regr )
  26. { int h,l, r ;
  27. r = (regr<<2) + 1 + cont;
  28. op(1); vl(r); op(0);
  29. switch (pi->mode) {
  30. case 0: w2(4); w2(6); l = r1();
  31. w2(4); w2(6); h = r1();
  32. w2(4); w2(6); w2(4); w2(6); w2(4);
  33. return j44(l,h);
  34. case 1: w2(4); w2(0x26); r = r0();
  35. w2(4); w2(0x26); w2(4);
  36. return r;
  37. }
  38. return -1;
  39. }
  40. static void on20_write_regr( PIA *pi, int cont, int regr, int val )
  41. { int r;
  42. r = (regr<<2) + 1 + cont;
  43. op(1); vl(r);
  44. op(0); vl(val);
  45. op(0); vl(val);
  46. }
  47. static void on20_connect ( PIA *pi)
  48. { pi->saved_r0 = r0();
  49. pi->saved_r2 = r2();
  50. w2(4);w0(0);w2(0xc);w2(4);w2(6);w2(4);w2(6);w2(4);
  51. if (pi->mode) { op(2); vl(8); op(2); vl(9); }
  52. else { op(2); vl(0); op(2); vl(8); }
  53. }
  54. static void on20_disconnect ( PIA *pi )
  55. { w2(4);w0(7);w2(4);w2(0xc);w2(4);
  56. w0(pi->saved_r0);
  57. w2(pi->saved_r2);
  58. }
  59. static void on20_read_block( PIA *pi, char * buf, int count )
  60. { int k, l, h;
  61. op(1); vl(1); op(0);
  62. for (k=0;k<count;k++)
  63. if (pi->mode) {
  64. w2(4); w2(0x26); buf[k] = r0();
  65. } else {
  66. w2(6); l = r1(); w2(4);
  67. w2(6); h = r1(); w2(4);
  68. buf[k] = j44(l,h);
  69. }
  70. w2(4);
  71. }
  72. static void on20_write_block( PIA *pi, char * buf, int count )
  73. { int k;
  74. op(1); vl(1); op(0);
  75. for (k=0;k<count;k++) { w2(5); w0(buf[k]); w2(7); }
  76. w2(4);
  77. }
  78. static void on20_log_adapter( PIA *pi, char * scratch, int verbose )
  79. { char *mode_string[2] = {"4-bit","8-bit"};
  80. printk("%s: on20 %s, OnSpec 90c20 at 0x%x, ",
  81. pi->device,ON20_VERSION,pi->port);
  82. printk("mode %d (%s), delay %d\n",pi->mode,
  83. mode_string[pi->mode],pi->delay);
  84. }
  85. static struct pi_protocol on20 = {
  86. .owner = THIS_MODULE,
  87. .name = "on20",
  88. .max_mode = 2,
  89. .epp_first = 2,
  90. .default_delay = 1,
  91. .max_units = 1,
  92. .write_regr = on20_write_regr,
  93. .read_regr = on20_read_regr,
  94. .write_block = on20_write_block,
  95. .read_block = on20_read_block,
  96. .connect = on20_connect,
  97. .disconnect = on20_disconnect,
  98. .log_adapter = on20_log_adapter,
  99. };
  100. static int __init on20_init(void)
  101. {
  102. return paride_register(&on20);
  103. }
  104. static void __exit on20_exit(void)
  105. {
  106. paride_unregister(&on20);
  107. }
  108. MODULE_LICENSE("GPL");
  109. module_init(on20_init)
  110. module_exit(on20_exit)