linux-old/arch/arm/mach-sa1100/adsbitsy.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-sa1100/adsbitsy.c
   3 *
   4 * Author: Woojung Huh
   5 *
   6 * Pieces specific to the ADS Bitsy
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License version 2 as
  10 * published by the Free Software Foundation.
  11 */
  12
  13#include <linux/init.h>
  14#include <linux/sched.h>
  15#include <linux/interrupt.h>
  16#include <linux/ptrace.h>
  17#include <linux/delay.h>
  18#include <linux/serial_core.h>
  19#include <linux/list.h>
  20#include <linux/timer.h>
  21
  22#include <asm/hardware.h>
  23#include <asm/hardware/sa1111.h>
  24#include <asm/setup.h>
  25#include <asm/irq.h>
  26
  27#include <asm/mach/irq.h>
  28#include <asm/mach/arch.h>
  29#include <asm/mach/map.h>
  30#include <asm/mach/serial_sa1100.h>
  31
  32#include <asm/arch/irq.h>
  33
  34#include "generic.h"
  35#include "sa1111.h"
  36
  37
  38static int __init adsbitsy_init(void)
  39{
  40        int ret;
  41
  42        if (!machine_is_adsbitsy())
  43                return -ENODEV;
  44
  45        /*
  46         * Ensure that the memory bus request/grant signals are setup,
  47         * and the grant is held in its inactive state
  48         */
  49        sa1110_mb_disable();
  50
  51        /* Bitsy uses GPIO pins for SPI interface to AVR
  52         * Bitsy Plus uses the standard pins instead.
  53         * it also needs to reset the AVR when booting
  54         */
  55
  56        PPAR |= PPAR_SSPGPIO;
  57
  58        /*
  59         * Reset SA1111
  60         */
  61        GPCR |= GPIO_GPIO26;
  62        udelay(1000);
  63        GPSR |= GPIO_GPIO26;
  64
  65
  66#ifndef CONFIG_LEDS_TIMER
  67        // Set Serial port 1 RTS and DTR Low during sleep
  68        PGSR |= GPIO_GPIO15 | GPIO_GPIO20;
  69#else
  70        // only RTS (because DTR is also the LED
  71        // which should be off during sleep);
  72        PGSR |= GPIO_GPIO15;
  73#endif
  74
  75        // Set Serial port 3RTS Low during sleep
  76        PGSR |= GPIO_GPIO19;
  77
  78        /*
  79         * Probe for SA1111.
  80         */
  81        ret = sa1111_probe(ADSBITSY_SA1111_BASE);
  82        if (ret < 0)
  83                return ret;
  84
  85        /*
  86         * We found it.  Wake the chip up.
  87         */
  88        sa1111_wake();
  89
  90        /*
  91         * The SDRAM configuration of the SA1110 and the SA1111 must
  92         * match.  This is very important to ensure that SA1111 accesses
  93         * don't corrupt the SDRAM.  Note that this ungates the SA1111's
  94         * MBGNT signal, so we must have called sa1110_mb_disable()
  95         * beforehand.
  96         */
  97        sa1111_configure_smc(1,
  98                             FExtr(MDCNFG, MDCNFG_SA1110_DRAC0),
  99                             FExtr(MDCNFG, MDCNFG_SA1110_TDL0));
 100
 101        /*
 102         * We only need to turn on DCLK whenever we want to use the
 103         * DMA.  It can otherwise be held firmly in the off position.
 104         */
 105        SKPCR |= SKPCR_DCLKEN;
 106
 107        /*
 108         * Enable the SA1110 memory bus request and grant signals.
 109         */
 110        sa1110_mb_enable();
 111
 112        set_GPIO_IRQ_edge(GPIO_GPIO0, GPIO_RISING_EDGE);
 113        sa1111_init_irq(IRQ_GPIO0);
 114
 115        return 0;
 116}
 117
 118__initcall(adsbitsy_init);
 119
 120static void __init adsbitsy_init_irq(void)
 121{
 122        /* First the standard SA1100 IRQs */
 123        sa1100_init_irq();
 124}
 125
 126
 127static struct map_desc adsbitsy_io_desc[] __initdata = {
 128 /* virtual     physical    length      domain     r  w  c  b */
 129  { 0xe8000000, 0x08000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* Flash bank 1 */
 130  { 0xf0000000, 0x3C000000, 0x00004000, DOMAIN_IO, 0, 1, 0, 0 }, /* 91C1111 */
 131  { 0xf4000000, 0x18000000, 0x00800000, DOMAIN_IO, 0, 1, 0, 0 }, /* SA1111 */
 132  LAST_DESC
 133};
 134
 135/* Use this to see when all uarts are shutdown.  Or all are closed.
 136 * We can only turn off RS232 chip if either of these are true.
 137 */
 138
 139static int uart_wake_count[3] = {1, 1, 1};
 140
 141enum {UART_SHUTDOWN, UART_WAKEUP};
 142
 143static void update_uart_counts(int line, int state)
 144{
 145        switch (state) {
 146        case UART_WAKEUP:
 147                uart_wake_count[line]++;
 148                break;
 149        case UART_SHUTDOWN:
 150                uart_wake_count[line]--;
 151                break;
 152        }
 153}
 154
 155static int adsbitsy_uart_open(struct uart_port *port, struct uart_info *info)
 156{
 157        if (port->mapbase == _Ser1UTCR0) {
 158                Ser1SDCR0 |= SDCR0_UART;
 159        } else if (port->mapbase == _Ser2UTCR0) {
 160                Ser2UTCR4 = Ser2HSCR0 = 0;
 161        }
 162        return 0;
 163}
 164
 165void adsbitsy_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
 166{
 167        // state has ACPI D0-D3
 168        // ACPI D0        : resume from suspend
 169        // ACPI D1-D3 : enter to a suspend state
 170        if (port->mapbase == _Ser1UTCR0) {
 171                if (state) {
 172                        update_uart_counts(1, UART_SHUTDOWN);
 173                        // disable uart
 174                        Ser1UTCR3 = 0;
 175                }
 176                else {
 177                        update_uart_counts(1, UART_WAKEUP);
 178                }
 179        }
 180        else if (port->mapbase == _Ser2UTCR0) {
 181                if (state) {
 182                        update_uart_counts(2, UART_SHUTDOWN);
 183                        // disable uart
 184                        Ser2UTCR3 = 0;
 185                        Ser2HSCR0 = 0;
 186                }
 187                else {
 188                        update_uart_counts(2, UART_WAKEUP);
 189                }
 190        }
 191        else if (port->mapbase == _Ser3UTCR0) {
 192                if (state) {
 193                        update_uart_counts(0, UART_SHUTDOWN);
 194                        // disable uart
 195                        Ser3UTCR3 = 0;
 196                }
 197                else {
 198                        update_uart_counts(0, UART_WAKEUP);
 199                }
 200        }
 201}
 202
 203static void adsbitsy_set_mctrl(struct uart_port *port, u_int mctrl)
 204{
 205        // note: only ports 1 and 3 have modem control
 206        if (port->mapbase == _Ser1UTCR0) {
 207                if (mctrl & TIOCM_RTS)
 208                        // Set RTS High
 209                        GPCR = GPIO_GPIO15;
 210                else
 211                        // Set RTS LOW
 212                        GPSR = GPIO_GPIO15;
 213                if (mctrl & TIOCM_DTR)
 214                        // Set DTR High
 215                        GPCR = GPIO_GPIO20;
 216                else
 217                        // Set DTR Low
 218                        GPSR = GPIO_GPIO20;
 219        } else if (port->mapbase == _Ser3UTCR0) {
 220                if (mctrl & TIOCM_RTS)
 221                        // Set RTS High
 222                        GPCR = GPIO_GPIO19;
 223                else
 224                        // Set RTS LOW
 225                        GPSR = GPIO_GPIO19;
 226        }
 227}
 228
 229static u_int adsbitsy_get_mctrl(struct uart_port *port)
 230{
 231        u_int ret = 0;
 232
 233        // note: only ports 1 and 3 have modem control
 234        if (port->mapbase == _Ser1UTCR0) {
 235                if (!(GPLR & GPIO_GPIO14))
 236                        ret |= TIOCM_CTS;
 237                if (!(GPLR & GPIO_GPIO24))
 238                        ret |= TIOCM_DSR;
 239                if (!(GPLR & GPIO_GPIO16))
 240                        ret |= TIOCM_RI;
 241                if (!(GPLR & GPIO_GPIO17))
 242                        ret |= TIOCM_CD;
 243        } else if (port->mapbase == _Ser3UTCR0) {
 244                if (!(GPLR & GPIO_GPIO18))
 245                        ret |= TIOCM_CTS;
 246        }
 247
 248        return ret;
 249}
 250
 251static struct sa1100_port_fns adsbitsy_port_fns __initdata = {
 252        .set_mctrl =    adsbitsy_set_mctrl,
 253        .get_mctrl =    adsbitsy_get_mctrl,
 254        .open =         adsbitsy_uart_open,
 255        .pm =           adsbitsy_uart_pm,
 256};
 257
 258static void __init adsbitsy_map_io(void)
 259{
 260        sa1100_map_io();
 261        iotable_init(adsbitsy_io_desc);
 262
 263        sa1100_register_uart_fns(&adsbitsy_port_fns);
 264        sa1100_register_uart(0, 3);
 265        sa1100_register_uart(1, 1);
 266
 267        // don't register if you want to use IRDA
 268#ifndef CONFIG_SA1100_FIR
 269        sa1100_register_uart(2, 2);
 270#endif
 271
 272        // COM1 Set RTS and DTR Output
 273        GPDR |= GPIO_GPIO15 | GPIO_GPIO20;
 274        // Set CTS, DSR, RI and CD Input
 275        GPDR &= ~(GPIO_GPIO14 | GPIO_GPIO24 | GPIO_GPIO16 | GPIO_GPIO17);
 276
 277        // COM3 Set RTS Output
 278        GPDR |= GPIO_GPIO19;
 279        // Set CTS Input
 280        GPDR &= ~GPIO_GPIO18;
 281}
 282
 283
 284MACHINE_START(ADSBITSY, "ADS Bitsy")
 285        BOOT_PARAMS(0xc000003c)
 286        BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
 287        MAPIO(adsbitsy_map_io)
 288        INITIRQ(adsbitsy_init_irq)
 289MACHINE_END
 290
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.