diff options
Diffstat (limited to 'target/linux/coldfire/patches/076-mcfv4e_irda.patch')
-rw-r--r-- | target/linux/coldfire/patches/076-mcfv4e_irda.patch | 237 |
1 files changed, 237 insertions, 0 deletions
diff --git a/target/linux/coldfire/patches/076-mcfv4e_irda.patch b/target/linux/coldfire/patches/076-mcfv4e_irda.patch new file mode 100644 index 0000000000..0452a47b24 --- /dev/null +++ b/target/linux/coldfire/patches/076-mcfv4e_irda.patch @@ -0,0 +1,237 @@ +From 5f645d0668b469c4738fe1e9d3994287a519d0f3 Mon Sep 17 00:00:00 2001 +From: Kurt Mahan <kmahan@freescale.com> +Date: Tue, 8 Jul 2008 15:57:47 -0600 +Subject: [PATCH] Add Coldfire IRDA support in serial driver. + +LTIBName: mcfv4e-irda +Signed-off-by: Kurt Mahan <kmahan@freescale.com> +Signed-off-by: Huan, Wang <b18965@freescale.com> +--- + drivers/serial/Kconfig | 6 ++ + drivers/serial/mcfserial.c | 110 ++++++++++++++++++++++++++++++++++++++++++-- + net/irda/irlap.c | 2 +- + 3 files changed, 113 insertions(+), 5 deletions(-) + +--- a/drivers/serial/Kconfig ++++ b/drivers/serial/Kconfig +@@ -979,6 +979,12 @@ config SERIAL_COLDFIRE + This driver supports the built-in serial ports of the Motorola ColdFire + family of CPUs. + ++config SERIAL_COLDFIRE_IRDA ++ bool "ColdFire IRDA support" ++ depends on SERIAL_COLDFIRE ++ help ++ This driver supports IRDA on the Motorola ColdFire. ++ + config SERIAL_MCF + bool "Coldfire serial support (new style driver)" + depends on COLDFIRE +--- a/drivers/serial/mcfserial.c ++++ b/drivers/serial/mcfserial.c +@@ -109,6 +109,10 @@ static struct tty_driver *mcfrs_serial_d + #define IRQBASE 73 + #endif + ++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA ++#define SERIAL_IRDA_LINE (2) ++#endif ++ + /* + * Configuration table, UARTs to look for at startup. + */ +@@ -393,6 +397,9 @@ static inline void receive_chars(struct + static inline void transmit_chars(struct mcf_serial *info) + { + volatile unsigned char *uartp; ++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA ++ int i; ++#endif + + uartp = info->addr; + +@@ -404,13 +411,36 @@ static inline void transmit_chars(struct + } + + if ((info->xmit_cnt <= 0) || info->tty->stopped) { ++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA ++ if (info->line == SERIAL_IRDA_LINE) { ++ /* Enable receiver for IRDA */ ++ uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; ++ /* reset RX */ ++ uartp[MCFUART_UCR] = MCFUART_UCR_TXENABLE | MCFUART_UCR_RXENABLE; ++ } ++#endif + info->imr &= ~MCFUART_UIR_TXREADY; + uartp[MCFUART_UIMR] = info->imr; + return; + } + + while (uartp[MCFUART_USR] & MCFUART_USR_TXREADY) { ++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA ++ if (info->line == SERIAL_IRDA_LINE) { ++ while (!(uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY)); ++ i = 0; ++ /* delay for settle */ ++#if defined(CONFIG_M548X) ++ udelay(1); ++#elif defined(CONFIG_M547X) ++ udelay(2); ++#else ++ while (i++ < 25000) udelay(1); ++#endif ++ } ++#endif + uartp[MCFUART_UTB] = info->xmit_buf[info->xmit_tail++]; ++ + info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); + info->stats.tx++; + if (--info->xmit_cnt <= 0) +@@ -567,6 +597,28 @@ static int startup(struct mcf_serial * i + */ + mcfrs_change_speed(info); + ++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA ++ if (info->line == SERIAL_IRDA_LINE) { ++ /* Put PSC in IrDA mode */ ++ MCF_PSC_SICR(info->line) = MCF_PSC_SICR_SIM_SIR; ++ ++ /* Set pulse width to 1.6 uS */ ++ MCF_PSC_IRSDR(info->line) = (uint8_t) ++ (16 * (CONFIG_MCFCLK / 10000000)); ++ MCF_PSC_IRCR1(info->line) = MCF_PSC_IRCR1_SPUL; ++ MCF_PSC_IRCR2(info->line) = 0; ++ ++ /* Enable RTS to send */ ++ MCF_PSC_OPSET(info->line) = MCF_PSC_OPSET_RTS; ++ ++ /* Setup FIFO Alarms */ ++ MCF_PSC_RFAR(info->line) = MCF_PSC_RFAR_ALARM(248); ++ MCF_PSC_TFAR(info->line) = MCF_PSC_TFAR_ALARM(248); ++ ++ MCF_PSC_RFCR(info->line) = MCF_PSC_RFCR_FRMEN | MCF_PSC_RFCR_GR(4); ++ MCF_PSC_TFCR(info->line) = MCF_PSC_TFCR_FRMEN | MCF_PSC_RFCR_GR(4); ++ } ++#endif + /* + * Lastly enable the UART transmitter and receiver, and + * interrupt enables. +@@ -588,10 +640,20 @@ static void shutdown(struct mcf_serial * + { + volatile unsigned char *uartp; + unsigned long flags; ++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA ++ unsigned long delay_counter = 0; ++#endif + + if (!(info->flags & ASYNC_INITIALIZED)) + return; +- ++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA ++ uartp = (volatile unsigned char *) info->addr; ++ while (!(uartp[MCFUART_USR] & MCFUART_USR_TXEMPTY)) { ++ if(delay_counter++ > 25000) ++ break; ++ udelay(10); ++ } ++#endif + #ifdef SERIAL_DEBUG_OPEN + printk("Shutting down serial port %d (irq %d)....\n", info->line, + info->irq); +@@ -820,10 +882,19 @@ static int mcfrs_write(struct tty_struct + + local_irq_disable(); + uartp = info->addr; ++ ++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA ++ if (info->line == SERIAL_IRDA_LINE) { ++ /* Disable IRDA receiver*/ ++ uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETRX; /* reset RX */ ++ uartp[MCFUART_UCR] = MCFUART_UCR_CMDRESETTX; /* reset TX */ ++ ++ uartp[MCFUART_UCR] = MCFUART_UCR_TXENABLE; ++ } ++#endif + info->imr |= MCFUART_UIR_TXREADY; + uartp[MCFUART_UIMR] = info->imr; + local_irq_restore(flags); +- + return total; + } + +@@ -884,9 +955,21 @@ static void mcfrs_throttle(struct tty_st + + if (serial_paranoia_check(info, tty->name, "mcfrs_throttle")) + return; +- ++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA ++ if (I_IXOFF(tty)) { ++ /* Force STOP_CHAR (xoff) out */ ++ volatile unsigned char *uartp; ++ unsigned long flags; ++ uartp = (volatile unsigned char *) info->addr; ++ local_irq_save(flags); ++ info->imr |= MCFUART_UIR_TXREADY; ++ uartp[MCFUART_UIMR] = info->imr; ++ local_irq_restore(flags); ++ } ++#else + if (I_IXOFF(tty)) + info->x_char = STOP_CHAR(tty); ++#endif + + /* Turn off RTS line (do this atomic) */ + } +@@ -907,8 +990,22 @@ static void mcfrs_unthrottle(struct tty_ + if (I_IXOFF(tty)) { + if (info->x_char) + info->x_char = 0; ++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA ++ else { ++ /* Force START_CHAR (xon) out */ ++ volatile unsigned char *uartp; ++ unsigned long flags; ++ info->x_char = START_CHAR(tty); ++ uartp = (volatile unsigned char *) info->addr; ++ local_irq_save(flags); ++ info->imr |= MCFUART_UIR_TXREADY; ++ uartp[MCFUART_UIMR] = info->imr; ++ local_irq_restore(flags); ++ } ++#else + else + info->x_char = START_CHAR(tty); ++#endif + } + + /* Assert RTS line (do this atomic) */ +@@ -1156,12 +1253,17 @@ static int mcfrs_ioctl(struct tty_struct + static void mcfrs_set_termios(struct tty_struct *tty, struct ktermios *old_termios) + { + struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; ++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA ++ int i = 0; /* hush GCC */ ++#endif + + if (tty->termios->c_cflag == old_termios->c_cflag) + return; + ++#ifdef CONFIG_SERIAL_COLDFIRE_IRDA ++ while (i++ < 35000) udelay(1); ++#endif + mcfrs_change_speed(info); +- + if ((old_termios->c_cflag & CRTSCTS) && + !(tty->termios->c_cflag & CRTSCTS)) { + tty->hw_stopped = 0; +--- a/net/irda/irlap.c ++++ b/net/irda/irlap.c +@@ -627,7 +627,7 @@ void irlap_status_indication(struct irla + { + switch (quality_of_link) { + case STATUS_NO_ACTIVITY: +- IRDA_MESSAGE("IrLAP, no activity on link!\n"); ++ /* IRDA_MESSAGE("IrLAP, no activity on link!\n"); */ + break; + case STATUS_NOISY: + IRDA_MESSAGE("IrLAP, noisy link!\n"); |