girbil-sir.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /*********************************************************************
  2. *
  3. * Filename: girbil.c
  4. * Version: 1.2
  5. * Description: Implementation for the Greenwich GIrBIL dongle
  6. * Status: Experimental.
  7. * Author: Dag Brattli <dagb@cs.uit.no>
  8. * Created at: Sat Feb 6 21:02:33 1999
  9. * Modified at: Fri Dec 17 09:13:20 1999
  10. * Modified by: Dag Brattli <dagb@cs.uit.no>
  11. *
  12. * Copyright (c) 1999 Dag Brattli, All Rights Reserved.
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License as
  16. * published by the Free Software Foundation; either version 2 of
  17. * the License, or (at your option) any later version.
  18. *
  19. * Neither Dag Brattli nor University of Tromsø admit liability nor
  20. * provide warranty for any of this software. This material is
  21. * provided "AS-IS" and at no charge.
  22. *
  23. ********************************************************************/
  24. #include <linux/module.h>
  25. #include <linux/delay.h>
  26. #include <linux/init.h>
  27. #include <net/irda/irda.h>
  28. #include "sir-dev.h"
  29. static int girbil_reset(struct sir_dev *dev);
  30. static int girbil_open(struct sir_dev *dev);
  31. static int girbil_close(struct sir_dev *dev);
  32. static int girbil_change_speed(struct sir_dev *dev, unsigned speed);
  33. /* Control register 1 */
  34. #define GIRBIL_TXEN 0x01 /* Enable transmitter */
  35. #define GIRBIL_RXEN 0x02 /* Enable receiver */
  36. #define GIRBIL_ECAN 0x04 /* Cancel self emitted data */
  37. #define GIRBIL_ECHO 0x08 /* Echo control characters */
  38. /* LED Current Register (0x2) */
  39. #define GIRBIL_HIGH 0x20
  40. #define GIRBIL_MEDIUM 0x21
  41. #define GIRBIL_LOW 0x22
  42. /* Baud register (0x3) */
  43. #define GIRBIL_2400 0x30
  44. #define GIRBIL_4800 0x31
  45. #define GIRBIL_9600 0x32
  46. #define GIRBIL_19200 0x33
  47. #define GIRBIL_38400 0x34
  48. #define GIRBIL_57600 0x35
  49. #define GIRBIL_115200 0x36
  50. /* Mode register (0x4) */
  51. #define GIRBIL_IRDA 0x40
  52. #define GIRBIL_ASK 0x41
  53. /* Control register 2 (0x5) */
  54. #define GIRBIL_LOAD 0x51 /* Load the new baud rate value */
  55. static struct dongle_driver girbil = {
  56. .owner = THIS_MODULE,
  57. .driver_name = "Greenwich GIrBIL",
  58. .type = IRDA_GIRBIL_DONGLE,
  59. .open = girbil_open,
  60. .close = girbil_close,
  61. .reset = girbil_reset,
  62. .set_speed = girbil_change_speed,
  63. };
  64. static int __init girbil_sir_init(void)
  65. {
  66. return irda_register_dongle(&girbil);
  67. }
  68. static void __exit girbil_sir_cleanup(void)
  69. {
  70. irda_unregister_dongle(&girbil);
  71. }
  72. static int girbil_open(struct sir_dev *dev)
  73. {
  74. struct qos_info *qos = &dev->qos;
  75. /* Power on dongle */
  76. sirdev_set_dtr_rts(dev, TRUE, TRUE);
  77. qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
  78. qos->min_turn_time.bits = 0x03;
  79. irda_qos_bits_to_value(qos);
  80. /* irda thread waits 50 msec for power settling */
  81. return 0;
  82. }
  83. static int girbil_close(struct sir_dev *dev)
  84. {
  85. /* Power off dongle */
  86. sirdev_set_dtr_rts(dev, FALSE, FALSE);
  87. return 0;
  88. }
  89. /*
  90. * Function girbil_change_speed (dev, speed)
  91. *
  92. * Set the speed for the Girbil type dongle.
  93. *
  94. */
  95. #define GIRBIL_STATE_WAIT_SPEED (SIRDEV_STATE_DONGLE_SPEED + 1)
  96. static int girbil_change_speed(struct sir_dev *dev, unsigned speed)
  97. {
  98. unsigned state = dev->fsm.substate;
  99. unsigned delay = 0;
  100. u8 control[2];
  101. static int ret = 0;
  102. /* dongle alread reset - port and dongle at default speed */
  103. switch(state) {
  104. case SIRDEV_STATE_DONGLE_SPEED:
  105. /* Set DTR and Clear RTS to enter command mode */
  106. sirdev_set_dtr_rts(dev, FALSE, TRUE);
  107. udelay(25); /* better wait a little while */
  108. ret = 0;
  109. switch (speed) {
  110. default:
  111. ret = -EINVAL;
  112. /* fall through */
  113. case 9600:
  114. control[0] = GIRBIL_9600;
  115. break;
  116. case 19200:
  117. control[0] = GIRBIL_19200;
  118. break;
  119. case 34800:
  120. control[0] = GIRBIL_38400;
  121. break;
  122. case 57600:
  123. control[0] = GIRBIL_57600;
  124. break;
  125. case 115200:
  126. control[0] = GIRBIL_115200;
  127. break;
  128. }
  129. control[1] = GIRBIL_LOAD;
  130. /* Write control bytes */
  131. sirdev_raw_write(dev, control, 2);
  132. dev->speed = speed;
  133. state = GIRBIL_STATE_WAIT_SPEED;
  134. delay = 100;
  135. break;
  136. case GIRBIL_STATE_WAIT_SPEED:
  137. /* Go back to normal mode */
  138. sirdev_set_dtr_rts(dev, TRUE, TRUE);
  139. udelay(25); /* better wait a little while */
  140. break;
  141. default:
  142. net_err_ratelimited("%s - undefined state %d\n",
  143. __func__, state);
  144. ret = -EINVAL;
  145. break;
  146. }
  147. dev->fsm.substate = state;
  148. return (delay > 0) ? delay : ret;
  149. }
  150. /*
  151. * Function girbil_reset (driver)
  152. *
  153. * This function resets the girbil dongle.
  154. *
  155. * Algorithm:
  156. * 0. set RTS, and wait at least 5 ms
  157. * 1. clear RTS
  158. */
  159. #define GIRBIL_STATE_WAIT1_RESET (SIRDEV_STATE_DONGLE_RESET + 1)
  160. #define GIRBIL_STATE_WAIT2_RESET (SIRDEV_STATE_DONGLE_RESET + 2)
  161. #define GIRBIL_STATE_WAIT3_RESET (SIRDEV_STATE_DONGLE_RESET + 3)
  162. static int girbil_reset(struct sir_dev *dev)
  163. {
  164. unsigned state = dev->fsm.substate;
  165. unsigned delay = 0;
  166. u8 control = GIRBIL_TXEN | GIRBIL_RXEN;
  167. int ret = 0;
  168. switch (state) {
  169. case SIRDEV_STATE_DONGLE_RESET:
  170. /* Reset dongle */
  171. sirdev_set_dtr_rts(dev, TRUE, FALSE);
  172. /* Sleep at least 5 ms */
  173. delay = 20;
  174. state = GIRBIL_STATE_WAIT1_RESET;
  175. break;
  176. case GIRBIL_STATE_WAIT1_RESET:
  177. /* Set DTR and clear RTS to enter command mode */
  178. sirdev_set_dtr_rts(dev, FALSE, TRUE);
  179. delay = 20;
  180. state = GIRBIL_STATE_WAIT2_RESET;
  181. break;
  182. case GIRBIL_STATE_WAIT2_RESET:
  183. /* Write control byte */
  184. sirdev_raw_write(dev, &control, 1);
  185. delay = 20;
  186. state = GIRBIL_STATE_WAIT3_RESET;
  187. break;
  188. case GIRBIL_STATE_WAIT3_RESET:
  189. /* Go back to normal mode */
  190. sirdev_set_dtr_rts(dev, TRUE, TRUE);
  191. dev->speed = 9600;
  192. break;
  193. default:
  194. net_err_ratelimited("%s(), undefined state %d\n",
  195. __func__, state);
  196. ret = -1;
  197. break;
  198. }
  199. dev->fsm.substate = state;
  200. return (delay > 0) ? delay : ret;
  201. }
  202. MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
  203. MODULE_DESCRIPTION("Greenwich GIrBIL dongle driver");
  204. MODULE_LICENSE("GPL");
  205. MODULE_ALIAS("irda-dongle-4"); /* IRDA_GIRBIL_DONGLE */
  206. module_init(girbil_sir_init);
  207. module_exit(girbil_sir_cleanup);