linux/arch/arm/mach-mx3/mx31moboard.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2008 Valentin Longchamp, EPFL Mobots group
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License as published by
   6 * the Free Software Foundation; either version 2 of the License, or
   7 * (at your option) any later version.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, write to the Free Software
  16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17 */
  18
  19#include <linux/delay.h>
  20#include <linux/fsl_devices.h>
  21#include <linux/gpio.h>
  22#include <linux/init.h>
  23#include <linux/interrupt.h>
  24#include <linux/leds.h>
  25#include <linux/memory.h>
  26#include <linux/mtd/physmap.h>
  27#include <linux/mtd/partitions.h>
  28#include <linux/platform_device.h>
  29#include <linux/types.h>
  30
  31#include <asm/mach-types.h>
  32#include <asm/mach/arch.h>
  33#include <asm/mach/time.h>
  34#include <asm/mach/map.h>
  35#include <mach/board-mx31moboard.h>
  36#include <mach/common.h>
  37#include <mach/hardware.h>
  38#include <mach/imx-uart.h>
  39#include <mach/iomux-mx3.h>
  40#include <mach/i2c.h>
  41#include <mach/mmc.h>
  42#include <mach/mx31.h>
  43
  44#include "devices.h"
  45
  46static unsigned int moboard_pins[] = {
  47        /* UART0 */
  48        MX31_PIN_CTS1__CTS1, MX31_PIN_RTS1__RTS1,
  49        MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1,
  50        /* UART4 */
  51        MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5,
  52        MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5,
  53        /* I2C0 */
  54        MX31_PIN_I2C_DAT__I2C1_SDA, MX31_PIN_I2C_CLK__I2C1_SCL,
  55        /* I2C1 */
  56        MX31_PIN_DCD_DTE1__I2C2_SDA, MX31_PIN_RI_DTE1__I2C2_SCL,
  57        /* SDHC1 */
  58        MX31_PIN_SD1_DATA3__SD1_DATA3, MX31_PIN_SD1_DATA2__SD1_DATA2,
  59        MX31_PIN_SD1_DATA1__SD1_DATA1, MX31_PIN_SD1_DATA0__SD1_DATA0,
  60        MX31_PIN_SD1_CLK__SD1_CLK, MX31_PIN_SD1_CMD__SD1_CMD,
  61        MX31_PIN_ATA_CS0__GPIO3_26, MX31_PIN_ATA_CS1__GPIO3_27,
  62        /* USB reset */
  63        MX31_PIN_GPIO1_0__GPIO1_0,
  64        /* USB OTG */
  65        MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
  66        MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
  67        MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
  68        MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
  69        MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
  70        MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
  71        MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
  72        MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
  73        MX31_PIN_USBOTG_CLK__USBOTG_CLK, MX31_PIN_USBOTG_DIR__USBOTG_DIR,
  74        MX31_PIN_USBOTG_NXT__USBOTG_NXT, MX31_PIN_USBOTG_STP__USBOTG_STP,
  75        MX31_PIN_USB_OC__GPIO1_30,
  76        /* LEDs */
  77        MX31_PIN_SVEN0__GPIO2_0, MX31_PIN_STX0__GPIO2_1,
  78        MX31_PIN_SRX0__GPIO2_2, MX31_PIN_SIMPD0__GPIO2_3,
  79        /* SEL */
  80        MX31_PIN_DTR_DCE1__GPIO2_8, MX31_PIN_DSR_DCE1__GPIO2_9,
  81        MX31_PIN_RI_DCE1__GPIO2_10, MX31_PIN_DCD_DCE1__GPIO2_11,
  82};
  83
  84static struct physmap_flash_data mx31moboard_flash_data = {
  85        .width          = 2,
  86};
  87
  88static struct resource mx31moboard_flash_resource = {
  89        .start  = 0xa0000000,
  90        .end    = 0xa1ffffff,
  91        .flags  = IORESOURCE_MEM,
  92};
  93
  94static struct platform_device mx31moboard_flash = {
  95        .name   = "physmap-flash",
  96        .id     = 0,
  97        .dev    = {
  98                .platform_data  = &mx31moboard_flash_data,
  99        },
 100        .resource = &mx31moboard_flash_resource,
 101        .num_resources = 1,
 102};
 103
 104static struct imxuart_platform_data uart_pdata = {
 105        .flags = IMXUART_HAVE_RTSCTS,
 106};
 107
 108static struct imxi2c_platform_data moboard_i2c0_pdata = {
 109        .bitrate = 400000,
 110};
 111
 112static struct imxi2c_platform_data moboard_i2c1_pdata = {
 113        .bitrate = 100000,
 114};
 115
 116#define SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_ATA_CS0)
 117#define SDHC1_WP IOMUX_TO_GPIO(MX31_PIN_ATA_CS1)
 118
 119static int moboard_sdhc1_get_ro(struct device *dev)
 120{
 121        return !gpio_get_value(SDHC1_WP);
 122}
 123
 124static int moboard_sdhc1_init(struct device *dev, irq_handler_t detect_irq,
 125                void *data)
 126{
 127        int ret;
 128
 129        ret = gpio_request(SDHC1_CD, "sdhc-detect");
 130        if (ret)
 131                return ret;
 132
 133        gpio_direction_input(SDHC1_CD);
 134
 135        ret = gpio_request(SDHC1_WP, "sdhc-wp");
 136        if (ret)
 137                goto err_gpio_free;
 138        gpio_direction_input(SDHC1_WP);
 139
 140        ret = request_irq(gpio_to_irq(SDHC1_CD), detect_irq,
 141                IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 142                "sdhc1-card-detect", data);
 143        if (ret)
 144                goto err_gpio_free_2;
 145
 146        return 0;
 147
 148err_gpio_free_2:
 149        gpio_free(SDHC1_WP);
 150err_gpio_free:
 151        gpio_free(SDHC1_CD);
 152
 153        return ret;
 154}
 155
 156static void moboard_sdhc1_exit(struct device *dev, void *data)
 157{
 158        free_irq(gpio_to_irq(SDHC1_CD), data);
 159        gpio_free(SDHC1_WP);
 160        gpio_free(SDHC1_CD);
 161}
 162
 163static struct imxmmc_platform_data sdhc1_pdata = {
 164        .get_ro = moboard_sdhc1_get_ro,
 165        .init   = moboard_sdhc1_init,
 166        .exit   = moboard_sdhc1_exit,
 167};
 168
 169/*
 170 * this pin is dedicated for all mx31moboard systems, so we do it here
 171 */
 172#define USB_RESET_B     IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)
 173
 174static void usb_xcvr_reset(void)
 175{
 176        gpio_request(USB_RESET_B, "usb-reset");
 177        gpio_direction_output(USB_RESET_B, 0);
 178        mdelay(1);
 179        gpio_set_value(USB_RESET_B, 1);
 180}
 181
 182#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
 183                        PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
 184
 185#define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
 186
 187static void moboard_usbotg_init(void)
 188{
 189        mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
 190        mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
 191        mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
 192        mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
 193        mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
 194        mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
 195        mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
 196        mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
 197        mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
 198        mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
 199        mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
 200        mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
 201
 202        gpio_request(OTG_EN_B, "usb-udc-en");
 203        gpio_direction_output(OTG_EN_B, 0);
 204}
 205
 206static struct fsl_usb2_platform_data usb_pdata = {
 207        .operating_mode = FSL_USB2_DR_DEVICE,
 208        .phy_mode       = FSL_USB2_PHY_ULPI,
 209};
 210
 211static struct gpio_led mx31moboard_leds[] = {
 212        {
 213                .name   = "coreboard-led-0:red:running",
 214                .default_trigger = "heartbeat",
 215                .gpio   = IOMUX_TO_GPIO(MX31_PIN_SVEN0),
 216        }, {
 217                .name   = "coreboard-led-1:red",
 218                .gpio   = IOMUX_TO_GPIO(MX31_PIN_STX0),
 219        }, {
 220                .name   = "coreboard-led-2:red",
 221                .gpio   = IOMUX_TO_GPIO(MX31_PIN_SRX0),
 222        }, {
 223                .name   = "coreboard-led-3:red",
 224                .gpio   = IOMUX_TO_GPIO(MX31_PIN_SIMPD0),
 225        },
 226};
 227
 228static struct gpio_led_platform_data mx31moboard_led_pdata = {
 229        .num_leds       = ARRAY_SIZE(mx31moboard_leds),
 230        .leds           = mx31moboard_leds,
 231};
 232
 233static struct platform_device mx31moboard_leds_device = {
 234        .name   = "leds-gpio",
 235        .id     = -1,
 236        .dev    = {
 237                .platform_data = &mx31moboard_led_pdata,
 238        },
 239};
 240
 241#define SEL0 IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
 242#define SEL1 IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
 243#define SEL2 IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
 244#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
 245
 246static void mx31moboard_init_sel_gpios(void)
 247{
 248        if (!gpio_request(SEL0, "sel0")) {
 249                gpio_direction_input(SEL0);
 250                gpio_export(SEL0, true);
 251        }
 252
 253        if (!gpio_request(SEL1, "sel1")) {
 254                gpio_direction_input(SEL1);
 255                gpio_export(SEL1, true);
 256        }
 257
 258        if (!gpio_request(SEL2, "sel2")) {
 259                gpio_direction_input(SEL2);
 260                gpio_export(SEL2, true);
 261        }
 262
 263        if (!gpio_request(SEL3, "sel3")) {
 264                gpio_direction_input(SEL3);
 265                gpio_export(SEL3, true);
 266        }
 267}
 268
 269static struct platform_device *devices[] __initdata = {
 270        &mx31moboard_flash,
 271        &mx31moboard_leds_device,
 272};
 273
 274static int mx31moboard_baseboard;
 275core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444);
 276
 277/*
 278 * Board specific initialization.
 279 */
 280static void __init mxc_board_init(void)
 281{
 282        mxc_iomux_setup_multiple_pins(moboard_pins, ARRAY_SIZE(moboard_pins),
 283                "moboard");
 284
 285        platform_add_devices(devices, ARRAY_SIZE(devices));
 286
 287        mxc_register_device(&mxc_uart_device0, &uart_pdata);
 288        mxc_register_device(&mxc_uart_device4, &uart_pdata);
 289
 290        mx31moboard_init_sel_gpios();
 291
 292        mxc_register_device(&mxc_i2c_device0, &moboard_i2c0_pdata);
 293        mxc_register_device(&mxc_i2c_device1, &moboard_i2c1_pdata);
 294
 295        mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata);
 296
 297        usb_xcvr_reset();
 298
 299        moboard_usbotg_init();
 300        mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
 301
 302        switch (mx31moboard_baseboard) {
 303        case MX31NOBOARD:
 304                break;
 305        case MX31DEVBOARD:
 306                mx31moboard_devboard_init();
 307                break;
 308        case MX31MARXBOT:
 309                mx31moboard_marxbot_init();
 310                break;
 311        default:
 312                printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n",
 313                        mx31moboard_baseboard);
 314        }
 315}
 316
 317static void __init mx31moboard_timer_init(void)
 318{
 319        mx31_clocks_init(26000000);
 320}
 321
 322struct sys_timer mx31moboard_timer = {
 323        .init   = mx31moboard_timer_init,
 324};
 325
 326MACHINE_START(MX31MOBOARD, "EPFL Mobots mx31moboard")
 327        /* Maintainer: Valentin Longchamp, EPFL Mobots group */
 328        .phys_io        = AIPS1_BASE_ADDR,
 329        .io_pg_offst    = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
 330        .boot_params    = PHYS_OFFSET + 0x100,
 331        .map_io         = mx31_map_io,
 332        .init_irq       = mx31_init_irq,
 333        .init_machine   = mxc_board_init,
 334        .timer          = &mx31moboard_timer,
 335MACHINE_END
 336
 337