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