Root/target/linux/coldfire/patches/005-Add-serial-driver-and-irda-driver-support-for-MCF544.patch

1From 5c37079957c5e5555aa8284a879f8cc44fa8eb25 Mon Sep 17 00:00:00 2001
2From: Alison Wang <b18965@freescale.com>
3Date: Thu, 4 Aug 2011 09:59:39 +0800
4Subject: [PATCH 05/52] Add serial driver and irda driver support for MCF5445x and MCF547x/MCF548x
5
6Add common serial driver for MCF5445x and MCF547x/MCF548x.
7Also add irda support for MCF547x/MCF548x.
8
9Signed-off-by: Alison Wang <b18965@freescale.com>
10---
11 drivers/tty/serial/Kconfig | 20 ++++++++++
12 drivers/tty/serial/mcf.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
13 2 files changed, 107 insertions(+), 0 deletions(-)
14
15--- a/drivers/tty/serial/Kconfig
16+++ b/drivers/tty/serial/Kconfig
17@@ -1027,6 +1027,26 @@ config SERIAL_68328_RTS_CTS
18     bool "Support RTS/CTS on 68328 serial port"
19     depends on SERIAL_68328
20 
21+config SERIAL_COLDFIRE_IRDA
22+ bool "ColdFire IRDA support"
23+ depends on SERIAL_MCF
24+ help
25+ This driver supports IrDA on the ColdFire platform,
26+ such as MCF547x and MCF548x.
27+
28+ Say Y here if you want to use IrDA 1.1 SIR mode.
29+
30+config SERIAL_COLDFIRE_EDMA
31+ bool "ColdFire serial EDMA support"
32+ depends on SERIAL_MCF
33+ default n
34+ help
35+ Enables Enhanced Direct Memory Access(eDMA) in the Coldfire
36+ serial driver.
37+
38+ Say Y here if you want to use DMA processing of transmit
39+ and receive data for the serial driver.
40+
41 config SERIAL_MCF
42     bool "Coldfire serial support"
43     depends on COLDFIRE
44--- a/drivers/tty/serial/mcf.c
45+++ b/drivers/tty/serial/mcf.c
46@@ -4,6 +4,10 @@
47  * mcf.c -- Freescale ColdFire UART driver
48  *
49  * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com>
50+ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
51+ * Jason Jin Jason.Jin@freescale.com
52+ * Shrek Wu B16972@freescale.com
53+ * Chengju Cai b22600@freescale.com
54  *
55  * This program is free software; you can redistribute it and/or modify
56  * it under the terms of the GNU General Public License as published by
57@@ -23,9 +27,11 @@
58 #include <linux/serial.h>
59 #include <linux/serial_core.h>
60 #include <linux/io.h>
61+#include <linux/delay.h>
62 #include <asm/coldfire.h>
63 #include <asm/mcfsim.h>
64 #include <asm/mcfuart.h>
65+#include <asm/m5485psc.h>
66 #include <asm/nettel.h>
67 
68 /****************************************************************************/
69@@ -46,6 +52,10 @@
70 #define mcf_setppdtr(p, v) do { } while (0)
71 #endif
72 
73+#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
74+#define SERIAL_IRDA_LINE (2)
75+#endif
76+
77 /****************************************************************************/
78 
79 /*
80@@ -101,6 +111,15 @@ static void mcf_start_tx(struct uart_por
81 {
82     struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
83 
84+#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
85+ if (port->line == SERIAL_IRDA_LINE) {
86+ /* Disable IRDA receiver*/
87+ writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
88+ writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
89+
90+ writeb(MCFUART_UCR_TXENABLE, port->membase + MCFUART_UCR);
91+ }
92+#endif
93     pp->imr |= MCFUART_UIR_TXREADY;
94     writeb(pp->imr, port->membase + MCFUART_UIMR);
95 }
96@@ -154,6 +173,30 @@ static int mcf_startup(struct uart_port
97 
98     spin_lock_irqsave(&port->lock, flags);
99 
100+#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
101+ if (port->line == SERIAL_IRDA_LINE) {
102+ /* Put PSC in IrDA mode */
103+ MCF_PSC_SICR(port->line) = MCF_PSC_SICR_SIM_SIR;
104+
105+ /* Set pulse width to 1.6 uS */
106+ MCF_PSC_IRSDR(port->line) = (uint8_t)
107+ (16 * (CONFIG_MCFCLK / 10000000));
108+ MCF_PSC_IRCR1(port->line) = MCF_PSC_IRCR1_SPUL;
109+ MCF_PSC_IRCR2(port->line) = 0;
110+
111+ /* Enable RTS to send */
112+ MCF_PSC_OPSET(port->line) = MCF_PSC_OPSET_RTS;
113+
114+ /* Setup FIFO Alarms */
115+ MCF_PSC_RFAR(port->line) = MCF_PSC_RFAR_ALARM(248);
116+ MCF_PSC_TFAR(port->line) = MCF_PSC_TFAR_ALARM(248);
117+
118+ MCF_PSC_RFCR(port->line) = MCF_PSC_RFCR_FRMEN
119+ | MCF_PSC_RFCR_GR(4);
120+ MCF_PSC_TFCR(port->line) = MCF_PSC_TFCR_FRMEN
121+ | MCF_PSC_RFCR_GR(4);
122+ }
123+#endif
124     /* Reset UART, get it into known state... */
125     writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
126     writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
127@@ -177,7 +220,17 @@ static void mcf_shutdown(struct uart_por
128 {
129     struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
130     unsigned long flags;
131+#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
132+ unsigned long delay_counter = 0;
133+#endif
134 
135+#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
136+ while (!((readb(port->membase + MCFUART_USR)) & MCFUART_USR_TXEMPTY)) {
137+ if (delay_counter++ > 25000)
138+ break;
139+ udelay(10);
140+ }
141+#endif
142     spin_lock_irqsave(&port->lock, flags);
143 
144     /* Disable all interrupts now */
145@@ -202,7 +255,14 @@ static void mcf_set_termios(struct uart_
146     unsigned int baudfr;
147 #endif
148     unsigned char mr1, mr2;
149+#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
150+ int i = 0; /* hush GCC */
151+#endif
152 
153+#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
154+ while (i++ < 35000)
155+ udelay(1);
156+#endif
157     baud = uart_get_baud_rate(port, termios, old, 0, 230400);
158 #if defined(CONFIG_M5272)
159     baudclk = (MCF_BUSCLK / baud) / 32;
160@@ -331,6 +391,23 @@ static void mcf_tx_chars(struct mcf_uart
161     while (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) {
162         if (xmit->head == xmit->tail)
163             break;
164+#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
165+ if (port->line == SERIAL_IRDA_LINE) {
166+ while (!((readb(port->membase + MCFUART_USR))\
167+ & MCFUART_USR_TXEMPTY))
168+ ;
169+ /* delay for settle */
170+#if defined(CONFIG_M548X)
171+ udelay(1);
172+#elif defined(CONFIG_M547X)
173+ udelay(2);
174+#else
175+ int i = 0;
176+ while (i++ < 25000)
177+ udelay(1);
178+#endif
179+ }
180+#endif
181         writeb(xmit->buf[xmit->tail], port->membase + MCFUART_UTB);
182         xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1);
183         port->icount.tx++;
184@@ -340,6 +417,16 @@ static void mcf_tx_chars(struct mcf_uart
185         uart_write_wakeup(port);
186 
187     if (xmit->head == xmit->tail) {
188+#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
189+ if (port->line == SERIAL_IRDA_LINE) {
190+ /* Enable receiver for IRDA */
191+ writeb(MCFUART_UCR_CMDRESETRX,\
192+ port->membase + MCFUART_UCR);
193+ /* reset RX */
194+ writeb(MCFUART_UCR_TXENABLE | MCFUART_UCR_RXENABLE,\
195+ port->membase + MCFUART_UCR);
196+ }
197+#endif
198         pp->imr &= ~MCFUART_UIR_TXREADY;
199         writeb(pp->imr, port->membase + MCFUART_UIMR);
200     }
201

Archive Download this file



interactive