summaryrefslogtreecommitdiff
path: root/target/linux/coldfire/patches/005-Add-serial-driver-and-irda-driver-support-for-MCF544.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/coldfire/patches/005-Add-serial-driver-and-irda-driver-support-for-MCF544.patch')
-rw-r--r--target/linux/coldfire/patches/005-Add-serial-driver-and-irda-driver-support-for-MCF544.patch200
1 files changed, 200 insertions, 0 deletions
diff --git a/target/linux/coldfire/patches/005-Add-serial-driver-and-irda-driver-support-for-MCF544.patch b/target/linux/coldfire/patches/005-Add-serial-driver-and-irda-driver-support-for-MCF544.patch
new file mode 100644
index 0000000000..1ccbb123b6
--- /dev/null
+++ b/target/linux/coldfire/patches/005-Add-serial-driver-and-irda-driver-support-for-MCF544.patch
@@ -0,0 +1,200 @@
+From 5c37079957c5e5555aa8284a879f8cc44fa8eb25 Mon Sep 17 00:00:00 2001
+From: Alison Wang <b18965@freescale.com>
+Date: Thu, 4 Aug 2011 09:59:39 +0800
+Subject: [PATCH 05/52] Add serial driver and irda driver support for MCF5445x and MCF547x/MCF548x
+
+Add common serial driver for MCF5445x and MCF547x/MCF548x.
+Also add irda support for MCF547x/MCF548x.
+
+Signed-off-by: Alison Wang <b18965@freescale.com>
+---
+ drivers/tty/serial/Kconfig | 20 ++++++++++
+ drivers/tty/serial/mcf.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 107 insertions(+), 0 deletions(-)
+
+--- a/drivers/tty/serial/Kconfig
++++ b/drivers/tty/serial/Kconfig
+@@ -1027,6 +1027,26 @@ config SERIAL_68328_RTS_CTS
+ bool "Support RTS/CTS on 68328 serial port"
+ depends on SERIAL_68328
+
++config SERIAL_COLDFIRE_IRDA
++ bool "ColdFire IRDA support"
++ depends on SERIAL_MCF
++ help
++ This driver supports IrDA on the ColdFire platform,
++ such as MCF547x and MCF548x.
++
++ Say Y here if you want to use IrDA 1.1 SIR mode.
++
++config SERIAL_COLDFIRE_EDMA
++ bool "ColdFire serial EDMA support"
++ depends on SERIAL_MCF
++ default n
++ help
++ Enables Enhanced Direct Memory Access(eDMA) in the Coldfire
++ serial driver.
++
++ Say Y here if you want to use DMA processing of transmit
++ and receive data for the serial driver.
++
+ config SERIAL_MCF
+ bool "Coldfire serial support"
+ depends on COLDFIRE
+--- a/drivers/tty/serial/mcf.c
++++ b/drivers/tty/serial/mcf.c
+@@ -4,6 +4,10 @@
+ * mcf.c -- Freescale ColdFire UART driver
+ *
+ * (C) Copyright 2003-2007, Greg Ungerer <gerg@snapgear.com>
++ * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
++ * Jason Jin Jason.Jin@freescale.com
++ * Shrek Wu B16972@freescale.com
++ * Chengju Cai b22600@freescale.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -23,9 +27,11 @@
+ #include <linux/serial.h>
+ #include <linux/serial_core.h>
+ #include <linux/io.h>
++#include <linux/delay.h>
+ #include <asm/coldfire.h>
+ #include <asm/mcfsim.h>
+ #include <asm/mcfuart.h>
++#include <asm/m5485psc.h>
+ #include <asm/nettel.h>
+
+ /****************************************************************************/
+@@ -46,6 +52,10 @@
+ #define mcf_setppdtr(p, v) do { } while (0)
+ #endif
+
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++#define SERIAL_IRDA_LINE (2)
++#endif
++
+ /****************************************************************************/
+
+ /*
+@@ -101,6 +111,15 @@ static void mcf_start_tx(struct uart_por
+ {
+ struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
+
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++ if (port->line == SERIAL_IRDA_LINE) {
++ /* Disable IRDA receiver*/
++ writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
++ writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
++
++ writeb(MCFUART_UCR_TXENABLE, port->membase + MCFUART_UCR);
++ }
++#endif
+ pp->imr |= MCFUART_UIR_TXREADY;
+ writeb(pp->imr, port->membase + MCFUART_UIMR);
+ }
+@@ -154,6 +173,30 @@ static int mcf_startup(struct uart_port
+
+ spin_lock_irqsave(&port->lock, flags);
+
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++ if (port->line == SERIAL_IRDA_LINE) {
++ /* Put PSC in IrDA mode */
++ MCF_PSC_SICR(port->line) = MCF_PSC_SICR_SIM_SIR;
++
++ /* Set pulse width to 1.6 uS */
++ MCF_PSC_IRSDR(port->line) = (uint8_t)
++ (16 * (CONFIG_MCFCLK / 10000000));
++ MCF_PSC_IRCR1(port->line) = MCF_PSC_IRCR1_SPUL;
++ MCF_PSC_IRCR2(port->line) = 0;
++
++ /* Enable RTS to send */
++ MCF_PSC_OPSET(port->line) = MCF_PSC_OPSET_RTS;
++
++ /* Setup FIFO Alarms */
++ MCF_PSC_RFAR(port->line) = MCF_PSC_RFAR_ALARM(248);
++ MCF_PSC_TFAR(port->line) = MCF_PSC_TFAR_ALARM(248);
++
++ MCF_PSC_RFCR(port->line) = MCF_PSC_RFCR_FRMEN
++ | MCF_PSC_RFCR_GR(4);
++ MCF_PSC_TFCR(port->line) = MCF_PSC_TFCR_FRMEN
++ | MCF_PSC_RFCR_GR(4);
++ }
++#endif
+ /* Reset UART, get it into known state... */
+ writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR);
+ writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR);
+@@ -177,7 +220,17 @@ static void mcf_shutdown(struct uart_por
+ {
+ struct mcf_uart *pp = container_of(port, struct mcf_uart, port);
+ unsigned long flags;
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++ unsigned long delay_counter = 0;
++#endif
+
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++ while (!((readb(port->membase + MCFUART_USR)) & MCFUART_USR_TXEMPTY)) {
++ if (delay_counter++ > 25000)
++ break;
++ udelay(10);
++ }
++#endif
+ spin_lock_irqsave(&port->lock, flags);
+
+ /* Disable all interrupts now */
+@@ -202,7 +255,14 @@ static void mcf_set_termios(struct uart_
+ unsigned int baudfr;
+ #endif
+ unsigned char mr1, mr2;
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++ int i = 0; /* hush GCC */
++#endif
+
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++ while (i++ < 35000)
++ udelay(1);
++#endif
+ baud = uart_get_baud_rate(port, termios, old, 0, 230400);
+ #if defined(CONFIG_M5272)
+ baudclk = (MCF_BUSCLK / baud) / 32;
+@@ -331,6 +391,23 @@ static void mcf_tx_chars(struct mcf_uart
+ while (readb(port->membase + MCFUART_USR) & MCFUART_USR_TXREADY) {
+ if (xmit->head == xmit->tail)
+ break;
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++ if (port->line == SERIAL_IRDA_LINE) {
++ while (!((readb(port->membase + MCFUART_USR))\
++ & MCFUART_USR_TXEMPTY))
++ ;
++ /* delay for settle */
++#if defined(CONFIG_M548X)
++ udelay(1);
++#elif defined(CONFIG_M547X)
++ udelay(2);
++#else
++ int i = 0;
++ while (i++ < 25000)
++ udelay(1);
++#endif
++ }
++#endif
+ writeb(xmit->buf[xmit->tail], port->membase + MCFUART_UTB);
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE -1);
+ port->icount.tx++;
+@@ -340,6 +417,16 @@ static void mcf_tx_chars(struct mcf_uart
+ uart_write_wakeup(port);
+
+ if (xmit->head == xmit->tail) {
++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA
++ if (port->line == SERIAL_IRDA_LINE) {
++ /* Enable receiver for IRDA */
++ writeb(MCFUART_UCR_CMDRESETRX,\
++ port->membase + MCFUART_UCR);
++ /* reset RX */
++ writeb(MCFUART_UCR_TXENABLE | MCFUART_UCR_RXENABLE,\
++ port->membase + MCFUART_UCR);
++ }
++#endif
+ pp->imr &= ~MCFUART_UIR_TXREADY;
+ writeb(pp->imr, port->membase + MCFUART_UIMR);
+ }