tekram-sir.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*********************************************************************
  2. *
  3. * Filename: tekram.c
  4. * Version: 1.3
  5. * Description: Implementation of the Tekram IrMate IR-210B dongle
  6. * Status: Experimental.
  7. * Author: Dag Brattli <dagb@cs.uit.no>
  8. * Created at: Wed Oct 21 20:02:35 1998
  9. * Modified at: Sun Oct 27 22:02:38 2002
  10. * Modified by: Martin Diehl <mad@mdiehl.de>
  11. *
  12. * Copyright (c) 1998-1999 Dag Brattli,
  13. * Copyright (c) 2002 Martin Diehl,
  14. * All Rights Reserved.
  15. *
  16. * This program is free software; you can redistribute it and/or
  17. * modify it under the terms of the GNU General Public License as
  18. * published by the Free Software Foundation; either version 2 of
  19. * the License, or (at your option) any later version.
  20. *
  21. * Neither Dag Brattli nor University of Tromsø admit liability nor
  22. * provide warranty for any of this software. This material is
  23. * provided "AS-IS" and at no charge.
  24. *
  25. ********************************************************************/
  26. #include <linux/module.h>
  27. #include <linux/delay.h>
  28. #include <linux/init.h>
  29. #include <net/irda/irda.h>
  30. #include "sir-dev.h"
  31. static int tekram_delay = 150; /* default is 150 ms */
  32. module_param(tekram_delay, int, 0);
  33. MODULE_PARM_DESC(tekram_delay, "tekram dongle write complete delay");
  34. static int tekram_open(struct sir_dev *);
  35. static int tekram_close(struct sir_dev *);
  36. static int tekram_change_speed(struct sir_dev *, unsigned);
  37. static int tekram_reset(struct sir_dev *);
  38. #define TEKRAM_115200 0x00
  39. #define TEKRAM_57600 0x01
  40. #define TEKRAM_38400 0x02
  41. #define TEKRAM_19200 0x03
  42. #define TEKRAM_9600 0x04
  43. #define TEKRAM_PW 0x10 /* Pulse select bit */
  44. static struct dongle_driver tekram = {
  45. .owner = THIS_MODULE,
  46. .driver_name = "Tekram IR-210B",
  47. .type = IRDA_TEKRAM_DONGLE,
  48. .open = tekram_open,
  49. .close = tekram_close,
  50. .reset = tekram_reset,
  51. .set_speed = tekram_change_speed,
  52. };
  53. static int __init tekram_sir_init(void)
  54. {
  55. if (tekram_delay < 1 || tekram_delay > 500)
  56. tekram_delay = 200;
  57. pr_debug("%s - using %d ms delay\n",
  58. tekram.driver_name, tekram_delay);
  59. return irda_register_dongle(&tekram);
  60. }
  61. static void __exit tekram_sir_cleanup(void)
  62. {
  63. irda_unregister_dongle(&tekram);
  64. }
  65. static int tekram_open(struct sir_dev *dev)
  66. {
  67. struct qos_info *qos = &dev->qos;
  68. sirdev_set_dtr_rts(dev, TRUE, TRUE);
  69. qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
  70. qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */
  71. irda_qos_bits_to_value(qos);
  72. /* irda thread waits 50 msec for power settling */
  73. return 0;
  74. }
  75. static int tekram_close(struct sir_dev *dev)
  76. {
  77. /* Power off dongle */
  78. sirdev_set_dtr_rts(dev, FALSE, FALSE);
  79. return 0;
  80. }
  81. /*
  82. * Function tekram_change_speed (dev, state, speed)
  83. *
  84. * Set the speed for the Tekram IRMate 210 type dongle. Warning, this
  85. * function must be called with a process context!
  86. *
  87. * Algorithm
  88. * 1. clear DTR
  89. * 2. set RTS, and wait at least 7 us
  90. * 3. send Control Byte to the IR-210 through TXD to set new baud rate
  91. * wait until the stop bit of Control Byte is sent (for 9600 baud rate,
  92. * it takes about 100 msec)
  93. *
  94. * [oops, why 100 msec? sending 1 byte (10 bits) takes 1.05 msec
  95. * - is this probably to compensate for delays in tty layer?]
  96. *
  97. * 5. clear RTS (return to NORMAL Operation)
  98. * 6. wait at least 50 us, new setting (baud rate, etc) takes effect here
  99. * after
  100. */
  101. #define TEKRAM_STATE_WAIT_SPEED (SIRDEV_STATE_DONGLE_SPEED + 1)
  102. static int tekram_change_speed(struct sir_dev *dev, unsigned speed)
  103. {
  104. unsigned state = dev->fsm.substate;
  105. unsigned delay = 0;
  106. u8 byte;
  107. static int ret = 0;
  108. switch(state) {
  109. case SIRDEV_STATE_DONGLE_SPEED:
  110. switch (speed) {
  111. default:
  112. speed = 9600;
  113. ret = -EINVAL;
  114. /* fall thru */
  115. case 9600:
  116. byte = TEKRAM_PW|TEKRAM_9600;
  117. break;
  118. case 19200:
  119. byte = TEKRAM_PW|TEKRAM_19200;
  120. break;
  121. case 38400:
  122. byte = TEKRAM_PW|TEKRAM_38400;
  123. break;
  124. case 57600:
  125. byte = TEKRAM_PW|TEKRAM_57600;
  126. break;
  127. case 115200:
  128. byte = TEKRAM_115200;
  129. break;
  130. }
  131. /* Set DTR, Clear RTS */
  132. sirdev_set_dtr_rts(dev, TRUE, FALSE);
  133. /* Wait at least 7us */
  134. udelay(14);
  135. /* Write control byte */
  136. sirdev_raw_write(dev, &byte, 1);
  137. dev->speed = speed;
  138. state = TEKRAM_STATE_WAIT_SPEED;
  139. delay = tekram_delay;
  140. break;
  141. case TEKRAM_STATE_WAIT_SPEED:
  142. /* Set DTR, Set RTS */
  143. sirdev_set_dtr_rts(dev, TRUE, TRUE);
  144. udelay(50);
  145. break;
  146. default:
  147. net_err_ratelimited("%s - undefined state %d\n",
  148. __func__, state);
  149. ret = -EINVAL;
  150. break;
  151. }
  152. dev->fsm.substate = state;
  153. return (delay > 0) ? delay : ret;
  154. }
  155. /*
  156. * Function tekram_reset (driver)
  157. *
  158. * This function resets the tekram dongle. Warning, this function
  159. * must be called with a process context!!
  160. *
  161. * Algorithm:
  162. * 0. Clear RTS and DTR, and wait 50 ms (power off the IR-210 )
  163. * 1. clear RTS
  164. * 2. set DTR, and wait at least 1 ms
  165. * 3. clear DTR to SPACE state, wait at least 50 us for further
  166. * operation
  167. */
  168. static int tekram_reset(struct sir_dev *dev)
  169. {
  170. /* Clear DTR, Set RTS */
  171. sirdev_set_dtr_rts(dev, FALSE, TRUE);
  172. /* Should sleep 1 ms */
  173. msleep(1);
  174. /* Set DTR, Set RTS */
  175. sirdev_set_dtr_rts(dev, TRUE, TRUE);
  176. /* Wait at least 50 us */
  177. udelay(75);
  178. dev->speed = 9600;
  179. return 0;
  180. }
  181. MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
  182. MODULE_DESCRIPTION("Tekram IrMate IR-210B dongle driver");
  183. MODULE_LICENSE("GPL");
  184. MODULE_ALIAS("irda-dongle-0"); /* IRDA_TEKRAM_DONGLE */
  185. module_init(tekram_sir_init);
  186. module_exit(tekram_sir_cleanup);