linux/arch/m68knommu/platform/520x/config.c
<<
>>
Prefs
   1/***************************************************************************/
   2
   3/*
   4 *  linux/arch/m68knommu/platform/520x/config.c
   5 *
   6 *  Copyright (C) 2005,      Freescale (www.freescale.com)
   7 *  Copyright (C) 2005,      Intec Automation (mike@steroidmicros.com)
   8 *  Copyright (C) 1999-2007, Greg Ungerer (gerg@snapgear.com)
   9 *  Copyright (C) 2001-2003, SnapGear Inc. (www.snapgear.com)
  10 */
  11
  12/***************************************************************************/
  13
  14#include <linux/kernel.h>
  15#include <linux/param.h>
  16#include <linux/init.h>
  17#include <linux/io.h>
  18#include <linux/spi/spi.h>
  19#include <linux/gpio.h>
  20#include <asm/machdep.h>
  21#include <asm/coldfire.h>
  22#include <asm/mcfsim.h>
  23#include <asm/mcfuart.h>
  24#include <asm/mcfqspi.h>
  25
  26/***************************************************************************/
  27
  28static struct mcf_platform_uart m520x_uart_platform[] = {
  29        {
  30                .mapbase        = MCF_MBAR + MCFUART_BASE1,
  31                .irq            = MCFINT_VECBASE + MCFINT_UART0,
  32        },
  33        {
  34                .mapbase        = MCF_MBAR + MCFUART_BASE2,
  35                .irq            = MCFINT_VECBASE + MCFINT_UART1,
  36        },
  37        {
  38                .mapbase        = MCF_MBAR + MCFUART_BASE3,
  39                .irq            = MCFINT_VECBASE + MCFINT_UART2,
  40        },
  41        { },
  42};
  43
  44static struct platform_device m520x_uart = {
  45        .name                   = "mcfuart",
  46        .id                     = 0,
  47        .dev.platform_data      = m520x_uart_platform,
  48};
  49
  50static struct resource m520x_fec_resources[] = {
  51        {
  52                .start          = MCF_MBAR + 0x30000,
  53                .end            = MCF_MBAR + 0x30000 + 0x7ff,
  54                .flags          = IORESOURCE_MEM,
  55        },
  56        {
  57                .start          = 64 + 36,
  58                .end            = 64 + 36,
  59                .flags          = IORESOURCE_IRQ,
  60        },
  61        {
  62                .start          = 64 + 40,
  63                .end            = 64 + 40,
  64                .flags          = IORESOURCE_IRQ,
  65        },
  66        {
  67                .start          = 64 + 42,
  68                .end            = 64 + 42,
  69                .flags          = IORESOURCE_IRQ,
  70        },
  71};
  72
  73static struct platform_device m520x_fec = {
  74        .name                   = "fec",
  75        .id                     = 0,
  76        .num_resources          = ARRAY_SIZE(m520x_fec_resources),
  77        .resource               = m520x_fec_resources,
  78};
  79
  80#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
  81static struct resource m520x_qspi_resources[] = {
  82        {
  83                .start          = MCFQSPI_IOBASE,
  84                .end            = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
  85                .flags          = IORESOURCE_MEM,
  86        },
  87        {
  88                .start          = MCFINT_VECBASE + MCFINT_QSPI,
  89                .end            = MCFINT_VECBASE + MCFINT_QSPI,
  90                .flags          = IORESOURCE_IRQ,
  91        },
  92};
  93
  94#define MCFQSPI_CS0    62
  95#define MCFQSPI_CS1    63
  96#define MCFQSPI_CS2    44
  97
  98static int m520x_cs_setup(struct mcfqspi_cs_control *cs_control)
  99{
 100        int status;
 101
 102        status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
 103        if (status) {
 104                pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
 105                goto fail0;
 106        }
 107        status = gpio_direction_output(MCFQSPI_CS0, 1);
 108        if (status) {
 109                pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
 110                goto fail1;
 111        }
 112
 113        status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
 114        if (status) {
 115                pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
 116                goto fail1;
 117        }
 118        status = gpio_direction_output(MCFQSPI_CS1, 1);
 119        if (status) {
 120                pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
 121                goto fail2;
 122        }
 123
 124        status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
 125        if (status) {
 126                pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
 127                goto fail2;
 128        }
 129        status = gpio_direction_output(MCFQSPI_CS2, 1);
 130        if (status) {
 131                pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
 132                goto fail3;
 133        }
 134
 135        return 0;
 136
 137fail3:
 138        gpio_free(MCFQSPI_CS2);
 139fail2:
 140        gpio_free(MCFQSPI_CS1);
 141fail1:
 142        gpio_free(MCFQSPI_CS0);
 143fail0:
 144        return status;
 145}
 146
 147static void m520x_cs_teardown(struct mcfqspi_cs_control *cs_control)
 148{
 149        gpio_free(MCFQSPI_CS2);
 150        gpio_free(MCFQSPI_CS1);
 151        gpio_free(MCFQSPI_CS0);
 152}
 153
 154static void m520x_cs_select(struct mcfqspi_cs_control *cs_control,
 155                            u8 chip_select, bool cs_high)
 156{
 157        switch (chip_select) {
 158        case 0:
 159                gpio_set_value(MCFQSPI_CS0, cs_high);
 160                break;
 161        case 1:
 162                gpio_set_value(MCFQSPI_CS1, cs_high);
 163                break;
 164        case 2:
 165                gpio_set_value(MCFQSPI_CS2, cs_high);
 166                break;
 167        }
 168}
 169
 170static void m520x_cs_deselect(struct mcfqspi_cs_control *cs_control,
 171                              u8 chip_select, bool cs_high)
 172{
 173        switch (chip_select) {
 174        case 0:
 175                gpio_set_value(MCFQSPI_CS0, !cs_high);
 176                break;
 177        case 1:
 178                gpio_set_value(MCFQSPI_CS1, !cs_high);
 179                break;
 180        case 2:
 181                gpio_set_value(MCFQSPI_CS2, !cs_high);
 182                break;
 183        }
 184}
 185
 186static struct mcfqspi_cs_control m520x_cs_control = {
 187        .setup                  = m520x_cs_setup,
 188        .teardown               = m520x_cs_teardown,
 189        .select                 = m520x_cs_select,
 190        .deselect               = m520x_cs_deselect,
 191};
 192
 193static struct mcfqspi_platform_data m520x_qspi_data = {
 194        .bus_num                = 0,
 195        .num_chipselect         = 3,
 196        .cs_control             = &m520x_cs_control,
 197};
 198
 199static struct platform_device m520x_qspi = {
 200        .name                   = "mcfqspi",
 201        .id                     = 0,
 202        .num_resources          = ARRAY_SIZE(m520x_qspi_resources),
 203        .resource               = m520x_qspi_resources,
 204        .dev.platform_data      = &m520x_qspi_data,
 205};
 206
 207static void __init m520x_qspi_init(void)
 208{
 209        u16 par;
 210        /* setup Port QS for QSPI with gpio CS control */
 211        writeb(0x3f, MCF_IPSBAR + MCF_GPIO_PAR_QSPI);
 212        /* make U1CTS and U2RTS gpio for cs_control */
 213        par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
 214        par &= 0x00ff;
 215        writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART);
 216}
 217#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
 218
 219
 220static struct platform_device *m520x_devices[] __initdata = {
 221        &m520x_uart,
 222        &m520x_fec,
 223#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
 224        &m520x_qspi,
 225#endif
 226};
 227
 228/***************************************************************************/
 229
 230static void __init m520x_uart_init_line(int line, int irq)
 231{
 232        u16 par;
 233        u8 par2;
 234
 235        switch (line) {
 236        case 0:
 237                par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
 238                par |= MCF_GPIO_PAR_UART_PAR_UTXD0 |
 239                       MCF_GPIO_PAR_UART_PAR_URXD0;
 240                writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART);
 241                break;
 242        case 1:
 243                par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
 244                par |= MCF_GPIO_PAR_UART_PAR_UTXD1 |
 245                       MCF_GPIO_PAR_UART_PAR_URXD1;
 246                writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART);
 247                break;
 248        case 2:
 249                par2 = readb(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
 250                par2 &= ~0x0F;
 251                par2 |= MCF_GPIO_PAR_FECI2C_PAR_SCL_UTXD2 |
 252                        MCF_GPIO_PAR_FECI2C_PAR_SDA_URXD2;
 253                writeb(par2, MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
 254                break;
 255        }
 256}
 257
 258static void __init m520x_uarts_init(void)
 259{
 260        const int nrlines = ARRAY_SIZE(m520x_uart_platform);
 261        int line;
 262
 263        for (line = 0; (line < nrlines); line++)
 264                m520x_uart_init_line(line, m520x_uart_platform[line].irq);
 265}
 266
 267/***************************************************************************/
 268
 269static void __init m520x_fec_init(void)
 270{
 271        u8 v;
 272
 273        /* Set multi-function pins to ethernet mode */
 274        v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FEC);
 275        writeb(v | 0xf0, MCF_IPSBAR + MCF_GPIO_PAR_FEC);
 276
 277        v = readb(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
 278        writeb(v | 0x0f, MCF_IPSBAR + MCF_GPIO_PAR_FECI2C);
 279}
 280
 281/***************************************************************************/
 282
 283static void m520x_cpu_reset(void)
 284{
 285        local_irq_disable();
 286        __raw_writeb(MCF_RCR_SWRESET, MCF_RCR);
 287}
 288
 289/***************************************************************************/
 290
 291void __init config_BSP(char *commandp, int size)
 292{
 293        mach_reset = m520x_cpu_reset;
 294        m520x_uarts_init();
 295        m520x_fec_init();
 296#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
 297        m520x_qspi_init();
 298#endif
 299}
 300
 301/***************************************************************************/
 302
 303static int __init init_BSP(void)
 304{
 305        platform_add_devices(m520x_devices, ARRAY_SIZE(m520x_devices));
 306        return 0;
 307}
 308
 309arch_initcall(init_BSP);
 310
 311/***************************************************************************/
 312