girbil-sir.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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. IRDA_DEBUG(2, "%s()\n", __func__);
  76. /* Power on dongle */
  77. sirdev_set_dtr_rts(dev, TRUE, TRUE);
  78. qos->baud_rate.bits &= IR_9600|IR_19200|IR_38400|IR_57600|IR_115200;
  79. qos->min_turn_time.bits = 0x03;
  80. irda_qos_bits_to_value(qos);
  81. /* irda thread waits 50 msec for power settling */
  82. return 0;
  83. }
  84. static int girbil_close(struct sir_dev *dev)
  85. {
  86. IRDA_DEBUG(2, "%s()\n", __func__);
  87. /* Power off dongle */
  88. sirdev_set_dtr_rts(dev, FALSE, FALSE);
  89. return 0;
  90. }
  91. /*
  92. * Function girbil_change_speed (dev, speed)
  93. *
  94. * Set the speed for the Girbil type dongle.
  95. *
  96. */
  97. #define GIRBIL_STATE_WAIT_SPEED (SIRDEV_STATE_DONGLE_SPEED + 1)
  98. static int girbil_change_speed(struct sir_dev *dev, unsigned speed)
  99. {
  100. unsigned state = dev->fsm.substate;
  101. unsigned delay = 0;
  102. u8 control[2];
  103. static int ret = 0;
  104. IRDA_DEBUG(2, "%s()\n", __func__);
  105. /* dongle alread reset - port and dongle at default speed */
  106. switch(state) {
  107. case SIRDEV_STATE_DONGLE_SPEED:
  108. /* Set DTR and Clear RTS to enter command mode */
  109. sirdev_set_dtr_rts(dev, FALSE, TRUE);
  110. udelay(25); /* better wait a little while */
  111. ret = 0;
  112. switch (speed) {
  113. default:
  114. ret = -EINVAL;
  115. /* fall through */
  116. case 9600:
  117. control[0] = GIRBIL_9600;
  118. break;
  119. case 19200:
  120. control[0] = GIRBIL_19200;
  121. break;
  122. case 34800:
  123. control[0] = GIRBIL_38400;
  124. break;
  125. case 57600:
  126. control[0] = GIRBIL_57600;
  127. break;
  128. case 115200:
  129. control[0] = GIRBIL_115200;
  130. break;
  131. }
  132. control[1] = GIRBIL_LOAD;
  133. /* Write control bytes */
  134. sirdev_raw_write(dev, control, 2);
  135. dev->speed = speed;
  136. state = GIRBIL_STATE_WAIT_SPEED;
  137. delay = 100;
  138. break;
  139. case GIRBIL_STATE_WAIT_SPEED:
  140. /* Go back to normal mode */
  141. sirdev_set_dtr_rts(dev, TRUE, TRUE);
  142. udelay(25); /* better wait a little while */
  143. break;
  144. default:
  145. IRDA_ERROR("%s - undefined state %d\n", __func__, state);
  146. ret = -EINVAL;
  147. break;
  148. }
  149. dev->fsm.substate = state;
  150. return (delay > 0) ? delay : ret;
  151. }
  152. /*
  153. * Function girbil_reset (driver)
  154. *
  155. * This function resets the girbil dongle.
  156. *
  157. * Algorithm:
  158. * 0. set RTS, and wait at least 5 ms
  159. * 1. clear RTS
  160. */
  161. #define GIRBIL_STATE_WAIT1_RESET (SIRDEV_STATE_DONGLE_RESET + 1)
  162. #define GIRBIL_STATE_WAIT2_RESET (SIRDEV_STATE_DONGLE_RESET + 2)
  163. #define GIRBIL_STATE_WAIT3_RESET (SIRDEV_STATE_DONGLE_RESET + 3)
  164. static int girbil_reset(struct sir_dev *dev)
  165. {
  166. unsigned state = dev->fsm.substate;
  167. unsigned delay = 0;
  168. u8 control = GIRBIL_TXEN | GIRBIL_RXEN;
  169. int ret = 0;
  170. IRDA_DEBUG(2, "%s()\n", __func__);
  171. switch (state) {
  172. case SIRDEV_STATE_DONGLE_RESET:
  173. /* Reset dongle */
  174. sirdev_set_dtr_rts(dev, TRUE, FALSE);
  175. /* Sleep at least 5 ms */
  176. delay = 20;
  177. state = GIRBIL_STATE_WAIT1_RESET;
  178. break;
  179. case GIRBIL_STATE_WAIT1_RESET:
  180. /* Set DTR and clear RTS to enter command mode */
  181. sirdev_set_dtr_rts(dev, FALSE, TRUE);
  182. delay = 20;
  183. state = GIRBIL_STATE_WAIT2_RESET;
  184. break;
  185. case GIRBIL_STATE_WAIT2_RESET:
  186. /* Write control byte */
  187. sirdev_raw_write(dev, &control, 1);
  188. delay = 20;
  189. state = GIRBIL_STATE_WAIT3_RESET;
  190. break;
  191. case GIRBIL_STATE_WAIT3_RESET:
  192. /* Go back to normal mode */
  193. sirdev_set_dtr_rts(dev, TRUE, TRUE);
  194. dev->speed = 9600;
  195. break;
  196. default:
  197. IRDA_ERROR("%s(), undefined state %d\n", __func__, state);
  198. ret = -1;
  199. break;
  200. }
  201. dev->fsm.substate = state;
  202. return (delay > 0) ? delay : ret;
  203. }
  204. MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
  205. MODULE_DESCRIPTION("Greenwich GIrBIL dongle driver");
  206. MODULE_LICENSE("GPL");
  207. MODULE_ALIAS("irda-dongle-4"); /* IRDA_GIRBIL_DONGLE */
  208. module_init(girbil_sir_init);
  209. module_exit(girbil_sir_cleanup);