076-mcfv4e_irda.patch 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. From 5f645d0668b469c4738fe1e9d3994287a519d0f3 Mon Sep 17 00:00:00 2001
  2. From: Kurt Mahan <[email protected]>
  3. Date: Tue, 8 Jul 2008 15:57:47 -0600
  4. Subject: [PATCH] Add Coldfire IRDA support in serial driver.
  5. LTIBName: mcfv4e-irda
  6. Signed-off-by: Kurt Mahan <[email protected]>
  7. Signed-off-by: Huan, Wang <[email protected]>
  8. ---
  9. drivers/serial/Kconfig | 6 ++
  10. drivers/serial/mcfserial.c | 110 ++++++++++++++++++++++++++++++++++++++++++--
  11. net/irda/irlap.c | 2 +-
  12. 3 files changed, 113 insertions(+), 5 deletions(-)
  13. --- a/drivers/serial/Kconfig
  14. +++ b/drivers/serial/Kconfig
  15. @@ -979,6 +979,12 @@ config SERIAL_COLDFIRE
  16. This driver supports the built-in serial ports of the Motorola ColdFire
  17. family of CPUs.
  18. +config SERIAL_COLDFIRE_IRDA
  19. + bool "ColdFire IRDA support"
  20. + depends on SERIAL_COLDFIRE
  21. + help
  22. + This driver supports IRDA on the Motorola ColdFire.
  23. +
  24. config SERIAL_MCF
  25. bool "Coldfire serial support (new style driver)"
  26. depends on COLDFIRE
  27. --- a/drivers/serial/mcfserial.c
  28. +++ b/drivers/serial/mcfserial.c
  29. @@ -109,6 +109,10 @@ static struct tty_driver *mcfrs_serial_d
  30. #define IRQBASE 73
  31. #endif
  32. +#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
  33. +#define SERIAL_IRDA_LINE (2)
  34. +#endif
  35. +
  36. /*
  37. * Configuration table, UARTs to look for at startup.
  38. */
  39. @@ -393,6 +397,9 @@ static inline void receive_chars(struct
  40. static inline void transmit_chars(struct mcf_serial *info)
  41. {
  42. volatile unsigned char *uartp;
  43. +#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
  44. + int i;
  45. +#endif
  46. uartp = info->addr;
  47. @@ -404,13 +411,36 @@ static inline void transmit_chars(struct
  48. }
  49. if ((info->xmit_cnt <= 0) || info->tty->stopped) {
  50. +#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
  51. + if (info->line == SERIAL_IRDA_LINE) {
  52. + /* Enable receiver for IRDA */
  53. + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX;
  54. + /* reset RX */
  55. + uartp[MCFUART_UCR] = MCFUART_UCR_TXENABLE | MCFUART_UCR_RXENABLE;
  56. + }
  57. +#endif
  58. info->imr &= ~MCFUART_UIR_TXREADY;
  59. uartp[MCFUART_UIMR] = info->imr;
  60. return;
  61. }
  62. while (uartp[MCFUART_USR] & MCFUART_USR_TXREADY) {
  63. +#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
  64. + if (info->line == SERIAL_IRDA_LINE) {
  65. + while (!(uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY));
  66. + i = 0;
  67. + /* delay for settle */
  68. +#if defined(CONFIG_M548X)
  69. + udelay(1);
  70. +#elif defined(CONFIG_M547X)
  71. + udelay(2);
  72. +#else
  73. + while (i++ < 25000) udelay(1);
  74. +#endif
  75. + }
  76. +#endif
  77. uartp[MCFUART_UTB] = info->xmit_buf[info->xmit_tail++];
  78. +
  79. info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1);
  80. info->stats.tx++;
  81. if (--info->xmit_cnt <= 0)
  82. @@ -567,6 +597,28 @@ static int startup(struct mcf_serial * i
  83. */
  84. mcfrs_change_speed(info);
  85. +#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
  86. + if (info->line == SERIAL_IRDA_LINE) {
  87. + /* Put PSC in IrDA mode */
  88. + MCF_PSC_SICR(info->line) = MCF_PSC_SICR_SIM_SIR;
  89. +
  90. + /* Set pulse width to 1.6 uS */
  91. + MCF_PSC_IRSDR(info->line) = (uint8_t)
  92. + (16 * (CONFIG_MCFCLK / 10000000));
  93. + MCF_PSC_IRCR1(info->line) = MCF_PSC_IRCR1_SPUL;
  94. + MCF_PSC_IRCR2(info->line) = 0;
  95. +
  96. + /* Enable RTS to send */
  97. + MCF_PSC_OPSET(info->line) = MCF_PSC_OPSET_RTS;
  98. +
  99. + /* Setup FIFO Alarms */
  100. + MCF_PSC_RFAR(info->line) = MCF_PSC_RFAR_ALARM(248);
  101. + MCF_PSC_TFAR(info->line) = MCF_PSC_TFAR_ALARM(248);
  102. +
  103. + MCF_PSC_RFCR(info->line) = MCF_PSC_RFCR_FRMEN | MCF_PSC_RFCR_GR(4);
  104. + MCF_PSC_TFCR(info->line) = MCF_PSC_TFCR_FRMEN | MCF_PSC_RFCR_GR(4);
  105. + }
  106. +#endif
  107. /*
  108. * Lastly enable the UART transmitter and receiver, and
  109. * interrupt enables.
  110. @@ -588,10 +640,20 @@ static void shutdown(struct mcf_serial *
  111. {
  112. volatile unsigned char *uartp;
  113. unsigned long flags;
  114. +#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
  115. + unsigned long delay_counter = 0;
  116. +#endif
  117. if (!(info->flags & ASYNC_INITIALIZED))
  118. return;
  119. -
  120. +#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
  121. + uartp = (volatile unsigned char *) info->addr;
  122. + while (!(uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY)) {
  123. + if(delay_counter++ > 25000)
  124. + break;
  125. + udelay(10);
  126. + }
  127. +#endif
  128. #ifdef SERIAL_DEBUG_OPEN
  129. printk("Shutting down serial port %d (irq %d)....\n", info->line,
  130. info->irq);
  131. @@ -820,10 +882,19 @@ static int mcfrs_write(struct tty_struct
  132. local_irq_disable();
  133. uartp = info->addr;
  134. +
  135. +#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
  136. + if (info->line == SERIAL_IRDA_LINE) {
  137. + /* Disable IRDA receiver*/
  138. + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */
  139. + uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */
  140. +
  141. + uartp[MCFUART_UCR] = MCFUART_UCR_TXENABLE;
  142. + }
  143. +#endif
  144. info->imr |= MCFUART_UIR_TXREADY;
  145. uartp[MCFUART_UIMR] = info->imr;
  146. local_irq_restore(flags);
  147. -
  148. return total;
  149. }
  150. @@ -884,9 +955,21 @@ static void mcfrs_throttle(struct tty_st
  151. if (serial_paranoia_check(info, tty->name, "mcfrs_throttle"))
  152. return;
  153. -
  154. +#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
  155. + if (I_IXOFF(tty)) {
  156. + /* Force STOP_CHAR (xoff) out */
  157. + volatile unsigned char *uartp;
  158. + unsigned long flags;
  159. + uartp = (volatile unsigned char *) info->addr;
  160. + local_irq_save(flags);
  161. + info->imr |= MCFUART_UIR_TXREADY;
  162. + uartp[MCFUART_UIMR] = info->imr;
  163. + local_irq_restore(flags);
  164. + }
  165. +#else
  166. if (I_IXOFF(tty))
  167. info->x_char = STOP_CHAR(tty);
  168. +#endif
  169. /* Turn off RTS line (do this atomic) */
  170. }
  171. @@ -907,8 +990,22 @@ static void mcfrs_unthrottle(struct tty_
  172. if (I_IXOFF(tty)) {
  173. if (info->x_char)
  174. info->x_char = 0;
  175. +#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
  176. + else {
  177. + /* Force START_CHAR (xon) out */
  178. + volatile unsigned char *uartp;
  179. + unsigned long flags;
  180. + info->x_char = START_CHAR(tty);
  181. + uartp = (volatile unsigned char *) info->addr;
  182. + local_irq_save(flags);
  183. + info->imr |= MCFUART_UIR_TXREADY;
  184. + uartp[MCFUART_UIMR] = info->imr;
  185. + local_irq_restore(flags);
  186. + }
  187. +#else
  188. else
  189. info->x_char = START_CHAR(tty);
  190. +#endif
  191. }
  192. /* Assert RTS line (do this atomic) */
  193. @@ -1156,12 +1253,17 @@ static int mcfrs_ioctl(struct tty_struct
  194. static void mcfrs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
  195. {
  196. struct mcf_serial *info = (struct mcf_serial *)tty->driver_data;
  197. +#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
  198. + int i = 0; /* hush GCC */
  199. +#endif
  200. if (tty->termios->c_cflag == old_termios->c_cflag)
  201. return;
  202. +#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
  203. + while (i++ < 35000) udelay(1);
  204. +#endif
  205. mcfrs_change_speed(info);
  206. -
  207. if ((old_termios->c_cflag & CRTSCTS) &&
  208. !(tty->termios->c_cflag & CRTSCTS)) {
  209. tty->hw_stopped = 0;
  210. --- a/net/irda/irlap.c
  211. +++ b/net/irda/irlap.c
  212. @@ -627,7 +627,7 @@ void irlap_status_indication(struct irla
  213. {
  214. switch (quality_of_link) {
  215. case STATUS_NO_ACTIVITY:
  216. - IRDA_MESSAGE("IrLAP, no activity on link!\n");
  217. + /* IRDA_MESSAGE("IrLAP, no activity on link!\n"); */
  218. break;
  219. case STATUS_NOISY:
  220. IRDA_MESSAGE("IrLAP, noisy link!\n");