sh: use the common ascii hex helpers
[safe/jmp/linux-2.6] / drivers / serial / sh-sci.c
index 1f89496..ce6ee92 100644 (file)
@@ -4,6 +4,7 @@
  * SuperH on-chip serial module support.  (SCI with no FIFO / with FIFO)
  *
  *  Copyright (C) 2002 - 2006  Paul Mundt
+ *  Modified to support SH7720 SCIF. Markus Brunner, Mark Jonas (Jul 2007).
  *
  * based off of the old drivers/char/sh-sci.c by:
  *
@@ -12,6 +13,7 @@
  *   Modified to support multiple serial ports. Stuart Menefy (May 2000).
  *   Modified to support SecureEdge. David McCullough (2002)
  *   Modified to support SH7300 SCIF. Takashi Kusuda (Jun 2003).
+ *   Removed SH7300 support (Jul 2007).
  *
  * This file is subject to the terms and conditions of the GNU General Public
  * License.  See the file "COPYING" in the main directory of this archive
 #include <linux/delay.h>
 #include <linux/console.h>
 #include <linux/platform_device.h>
-
-#ifdef CONFIG_CPU_FREQ
+#include <linux/serial_sci.h>
 #include <linux/notifier.h>
 #include <linux/cpufreq.h>
-#endif
-
-#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+#include <linux/clk.h>
 #include <linux/ctype.h>
+
+#ifdef CONFIG_SUPERH
 #include <asm/clock.h>
 #include <asm/sh_bios.h>
 #include <asm/kgdb.h>
 #endif
 
-#include <asm/sci.h>
 #include "sh-sci.h"
 
 struct sci_port {
@@ -78,7 +78,7 @@ struct sci_port {
        struct timer_list       break_timer;
        int                     break_flag;
 
-#if defined(CONFIG_SUPERH) && !defined(CONFIG_SUPERH64)
+#ifdef CONFIG_SUPERH
        /* Port clock */
        struct clk              *clk;
 #endif
@@ -184,15 +184,15 @@ static void put_string(struct sci_port *sci_port, const char *buffer, int count)
                        int h, l;
 
                        c = *p++;
-                       h = highhex(c);
-                       l = lowhex(c);
+                       h = hex_asc_hi(c);
+                       l = hex_asc_lo(c);
                        put_char(port, h);
                        put_char(port, l);
                        checksum += h + l;
                }
                put_char(port, '#');
-               put_char(port, highhex(checksum));
-               put_char(port, lowhex(checksum));
+               put_char(port, hex_asc_hi(checksum));
+               put_char(port, hex_asc_lo(checksum));
            } while  (get_char(port) != '+');
        } else
 #endif /* CONFIG_SH_STANDARD_BIOS || CONFIG_SH_KGDB */
@@ -289,13 +289,7 @@ static void sci_init_pins_irda(struct uart_port *port, unsigned int cflag)
 #endif
 
 #if defined(SCIF_ONLY) || defined(SCI_AND_SCIF)
-#if defined(CONFIG_CPU_SUBTYPE_SH7300) 
-/* SH7300 doesn't use RTS/CTS */
-static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
-{
-       sci_out(port, SCFCR, 0);
-}
-#elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
+#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712)
 static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag)
 {
        unsigned int fcr_val = 0;
@@ -306,6 +300,37 @@ static void sci_init_pins_scif(struct uart_port* port, unsigned int cflag)
        }
        sci_out(port, SCFCR, fcr_val);
 }
+#elif defined(CONFIG_CPU_SUBTYPE_SH7720) || defined(CONFIG_CPU_SUBTYPE_SH7721)
+static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
+{
+       unsigned int fcr_val = 0;
+       unsigned short data;
+
+       if (cflag & CRTSCTS) {
+               /* enable RTS/CTS */
+               if (port->mapbase == 0xa4430000) { /* SCIF0 */
+                       /* Clear PTCR bit 9-2; enable all scif pins but sck */
+                       data = ctrl_inw(PORT_PTCR);
+                       ctrl_outw((data & 0xfc03), PORT_PTCR);
+               } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
+                       /* Clear PVCR bit 9-2 */
+                       data = ctrl_inw(PORT_PVCR);
+                       ctrl_outw((data & 0xfc03), PORT_PVCR);
+               }
+               fcr_val |= SCFCR_MCE;
+       } else {
+               if (port->mapbase == 0xa4430000) { /* SCIF0 */
+                       /* Clear PTCR bit 5-2; enable only tx and rx  */
+                       data = ctrl_inw(PORT_PTCR);
+                       ctrl_outw((data & 0xffc3), PORT_PTCR);
+               } else if (port->mapbase == 0xa4438000) { /* SCIF1 */
+                       /* Clear PVCR bit 5-2 */
+                       data = ctrl_inw(PORT_PVCR);
+                       ctrl_outw((data & 0xffc3), PORT_PVCR);
+               }
+       }
+       sci_out(port, SCFCR, fcr_val);
+}
 #elif defined(CONFIG_CPU_SH3)
 /* For SH7705, SH7706, SH7707, SH7709, SH7709A, SH7729 */
 static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
@@ -338,24 +363,28 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
 static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
 {
        unsigned int fcr_val = 0;
+       unsigned short data;
 
-       if (cflag & CRTSCTS) {
-               fcr_val |= SCFCR_MCE;
-
-               ctrl_outw(0x0000, PORT_PSCR);
-       } else {
-               unsigned short data;
-
-               data = ctrl_inw(PORT_PSCR);
-               data &= 0x033f;
-               data |= 0x0400;
-               ctrl_outw(data, PORT_PSCR);
+       if (port->mapbase == 0xffe00000) {
+               data = ctrl_inw(PSCR);
+               data &= ~0x03cf;
+               if (cflag & CRTSCTS)
+                       fcr_val |= SCFCR_MCE;
+               else
+                       data |= 0x0340;
 
-               ctrl_outw(ctrl_inw(SCSPTR0) & 0x17, SCSPTR0);
+               ctrl_outw(data, PSCR);
        }
+       /* SCIF1 and SCIF2 should be setup by board code */
 
        sci_out(port, SCFCR, fcr_val);
 }
+#elif defined(CONFIG_CPU_SUBTYPE_SH7723)
+static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
+{
+       /* Nothing to do here.. */
+       sci_out(port, SCFCR, 0);
+}
 #else
 /* For SH7750 */
 static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
@@ -365,9 +394,12 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
        if (cflag & CRTSCTS) {
                fcr_val |= SCFCR_MCE;
        } else {
-#ifdef CONFIG_CPU_SUBTYPE_SH7343
+#if defined(CONFIG_CPU_SUBTYPE_SH7343) || defined(CONFIG_CPU_SUBTYPE_SH7366)
                /* Nothing */
-#elif defined(CONFIG_CPU_SUBTYPE_SH7780) || defined(CONFIG_CPU_SUBTYPE_SH7785)
+#elif defined(CONFIG_CPU_SUBTYPE_SH7763) || \
+      defined(CONFIG_CPU_SUBTYPE_SH7780) || \
+      defined(CONFIG_CPU_SUBTYPE_SH7785) || \
+      defined(CONFIG_CPU_SUBTYPE_SHX3)
                ctrl_outw(0x0080, SCSPTR0); /* Set RTS = 1 */
 #else
                ctrl_outw(0x0080, SCSPTR2); /* Set RTS = 1 */
@@ -378,16 +410,17 @@ static void sci_init_pins_scif(struct uart_port *port, unsigned int cflag)
 #endif
 
 #if defined(CONFIG_CPU_SUBTYPE_SH7760) || \
+    defined(CONFIG_CPU_SUBTYPE_SH7763) || \
     defined(CONFIG_CPU_SUBTYPE_SH7780) || \
     defined(CONFIG_CPU_SUBTYPE_SH7785)
 static inline int scif_txroom(struct uart_port *port)
 {
-       return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0x7f);
+       return SCIF_TXROOM_MAX - (sci_in(port, SCTFDR) & 0xff);
 }
 
 static inline int scif_rxroom(struct uart_port *port)
 {
-       return sci_in(port, SCRFDR) & 0x7f;
+       return sci_in(port, SCRFDR) & 0xff;
 }
 #else
 static inline int scif_txroom(struct uart_port *port)
@@ -818,7 +851,7 @@ static int sci_notifier(struct notifier_block *self,
 
                printk(KERN_INFO "%s: got a postchange notification "
                       "for cpu %d (old %d, new %d)\n",
-                      __FUNCTION__, freqs->cpu, freqs->old, freqs->new);
+                      __func__, freqs->cpu, freqs->old, freqs->new);
        }
 
        return NOTIFY_OK;
@@ -1279,7 +1312,7 @@ static int __init sci_console_init(void)
 console_initcall(sci_console_init);
 #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */
 
-#ifdef CONFIG_SH_KGDB
+#ifdef CONFIG_SH_KGDB_CONSOLE
 /*
  * FIXME: Most of this can go away.. at the moment, we rely on
  * arch/sh/kernel/setup.c to do the command line parsing for kgdb, though
@@ -1337,9 +1370,7 @@ int __init kgdb_console_setup(struct console *co, char *options)
 
        return uart_set_options(port, co, baud, parity, bits, flow);
 }
-#endif /* CONFIG_SH_KGDB */
 
-#ifdef CONFIG_SH_KGDB_CONSOLE
 static struct console kgdb_console = {
        .name           = "ttySC",
        .device         = uart_console_device,
@@ -1435,7 +1466,7 @@ static int __devinit sci_probe(struct platform_device *dev)
 
 #ifdef CONFIG_CPU_FREQ
        cpufreq_register_notifier(&sci_nb, CPUFREQ_TRANSITION_NOTIFIER);
-       dev_info(&dev->dev, "sci: CPU frequency notifier registered\n");
+       dev_info(&dev->dev, "CPU frequency notifier registered\n");
 #endif
 
 #ifdef CONFIG_SH_STANDARD_BIOS
@@ -1522,3 +1553,4 @@ module_init(sci_init);
 module_exit(sci_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sh-sci");