tekram-sir.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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. IRDA_DEBUG(1, "%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. IRDA_DEBUG(2, "%s()\n", __func__);
  69. sirdev_set_dtr_rts(dev, TRUE, TRUE);
  70. qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
  71. qos->min_turn_time.bits = 0x01; /* Needs at least 10 ms */
  72. irda_qos_bits_to_value(qos);
  73. /* irda thread waits 50 msec for power settling */
  74. return 0;
  75. }
  76. static int tekram_close(struct sir_dev *dev)
  77. {
  78. IRDA_DEBUG(2, "%s()\n", __func__);
  79. /* Power off dongle */
  80. sirdev_set_dtr_rts(dev, FALSE, FALSE);
  81. return 0;
  82. }
  83. /*
  84. * Function tekram_change_speed (dev, state, speed)
  85. *
  86. * Set the speed for the Tekram IRMate 210 type dongle. Warning, this
  87. * function must be called with a process context!
  88. *
  89. * Algorithm
  90. * 1. clear DTR
  91. * 2. set RTS, and wait at least 7 us
  92. * 3. send Control Byte to the IR-210 through TXD to set new baud rate
  93. * wait until the stop bit of Control Byte is sent (for 9600 baud rate,
  94. * it takes about 100 msec)
  95. *
  96. * [oops, why 100 msec? sending 1 byte (10 bits) takes 1.05 msec
  97. * - is this probably to compensate for delays in tty layer?]
  98. *
  99. * 5. clear RTS (return to NORMAL Operation)
  100. * 6. wait at least 50 us, new setting (baud rate, etc) takes effect here
  101. * after
  102. */
  103. #define TEKRAM_STATE_WAIT_SPEED (SIRDEV_STATE_DONGLE_SPEED + 1)
  104. static int tekram_change_speed(struct sir_dev *dev, unsigned speed)
  105. {
  106. unsigned state = dev->fsm.substate;
  107. unsigned delay = 0;
  108. u8 byte;
  109. static int ret = 0;
  110. IRDA_DEBUG(2, "%s()\n", __func__);
  111. switch(state) {
  112. case SIRDEV_STATE_DONGLE_SPEED:
  113. switch (speed) {
  114. default:
  115. speed = 9600;
  116. ret = -EINVAL;
  117. /* fall thru */
  118. case 9600:
  119. byte = TEKRAM_PW|TEKRAM_9600;
  120. break;
  121. case 19200:
  122. byte = TEKRAM_PW|TEKRAM_19200;
  123. break;
  124. case 38400:
  125. byte = TEKRAM_PW|TEKRAM_38400;
  126. break;
  127. case 57600:
  128. byte = TEKRAM_PW|TEKRAM_57600;
  129. break;
  130. case 115200:
  131. byte = TEKRAM_115200;
  132. break;
  133. }
  134. /* Set DTR, Clear RTS */
  135. sirdev_set_dtr_rts(dev, TRUE, FALSE);
  136. /* Wait at least 7us */
  137. udelay(14);
  138. /* Write control byte */
  139. sirdev_raw_write(dev, &byte, 1);
  140. dev->speed = speed;
  141. state = TEKRAM_STATE_WAIT_SPEED;
  142. delay = tekram_delay;
  143. break;
  144. case TEKRAM_STATE_WAIT_SPEED:
  145. /* Set DTR, Set RTS */
  146. sirdev_set_dtr_rts(dev, TRUE, TRUE);
  147. udelay(50);
  148. break;
  149. default:
  150. IRDA_ERROR("%s - undefined state %d\n", __func__, state);
  151. ret = -EINVAL;
  152. break;
  153. }
  154. dev->fsm.substate = state;
  155. return (delay > 0) ? delay : ret;
  156. }
  157. /*
  158. * Function tekram_reset (driver)
  159. *
  160. * This function resets the tekram dongle. Warning, this function
  161. * must be called with a process context!!
  162. *
  163. * Algorithm:
  164. * 0. Clear RTS and DTR, and wait 50 ms (power off the IR-210 )
  165. * 1. clear RTS
  166. * 2. set DTR, and wait at least 1 ms
  167. * 3. clear DTR to SPACE state, wait at least 50 us for further
  168. * operation
  169. */
  170. static int tekram_reset(struct sir_dev *dev)
  171. {
  172. IRDA_DEBUG(2, "%s()\n", __func__);
  173. /* Clear DTR, Set RTS */
  174. sirdev_set_dtr_rts(dev, FALSE, TRUE);
  175. /* Should sleep 1 ms */
  176. msleep(1);
  177. /* Set DTR, Set RTS */
  178. sirdev_set_dtr_rts(dev, TRUE, TRUE);
  179. /* Wait at least 50 us */
  180. udelay(75);
  181. dev->speed = 9600;
  182. return 0;
  183. }
  184. MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
  185. MODULE_DESCRIPTION("Tekram IrMate IR-210B dongle driver");
  186. MODULE_LICENSE("GPL");
  187. MODULE_ALIAS("irda-dongle-0"); /* IRDA_TEKRAM_DONGLE */
  188. module_init(tekram_sir_init);
  189. module_exit(tekram_sir_cleanup);