1/* 2 * LogicPD i.MX31 SOM-LV development board support 3 * 4 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> 5 * 6 * based on code for other MX31 boards, 7 * 8 * Copyright 2005-2007 Freescale Semiconductor 9 * Copyright (c) 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> 10 * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 2 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 */ 22 23#include <linux/kernel.h> 24#include <linux/types.h> 25#include <linux/init.h> 26#include <linux/gpio.h> 27#include <linux/leds.h> 28#include <linux/platform_device.h> 29 30#include <asm/mach-types.h> 31#include <asm/mach/arch.h> 32#include <asm/mach/map.h> 33 34#include "board-mx31lite.h" 35#include "common.h" 36#include "devices-imx31.h" 37#include "hardware.h" 38#include "iomux-mx3.h" 39 40/* 41 * This file contains board-specific initialization routines for the 42 * LogicPD i.MX31 SOM-LV development board, aka 'LiteKit'. 43 * If you design an own baseboard for the module, use this file as base 44 * for support code. 45 */ 46 47static unsigned int litekit_db_board_pins[] __initdata = { 48 /* UART1 */ 49 MX31_PIN_CTS1__CTS1, 50 MX31_PIN_RTS1__RTS1, 51 MX31_PIN_TXD1__TXD1, 52 MX31_PIN_RXD1__RXD1, 53 /* SPI 0 */ 54 MX31_PIN_CSPI1_SCLK__SCLK, 55 MX31_PIN_CSPI1_MOSI__MOSI, 56 MX31_PIN_CSPI1_MISO__MISO, 57 MX31_PIN_CSPI1_SPI_RDY__SPI_RDY, 58 MX31_PIN_CSPI1_SS0__SS0, 59 MX31_PIN_CSPI1_SS1__SS1, 60 MX31_PIN_CSPI1_SS2__SS2, 61 /* SDHC1 */ 62 MX31_PIN_SD1_DATA0__SD1_DATA0, 63 MX31_PIN_SD1_DATA1__SD1_DATA1, 64 MX31_PIN_SD1_DATA2__SD1_DATA2, 65 MX31_PIN_SD1_DATA3__SD1_DATA3, 66 MX31_PIN_SD1_CLK__SD1_CLK, 67 MX31_PIN_SD1_CMD__SD1_CMD, 68}; 69 70/* UART */ 71static const struct imxuart_platform_data uart_pdata __initconst = { 72 .flags = IMXUART_HAVE_RTSCTS, 73}; 74 75/* MMC */ 76 77static int gpio_det, gpio_wp; 78 79#define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ 80 PAD_CTL_ODE_CMOS) 81 82static int mxc_mmc1_get_ro(struct device *dev) 83{ 84 return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_GPIO1_6)); 85} 86 87static int mxc_mmc1_init(struct device *dev, 88 irq_handler_t detect_irq, void *data) 89{ 90 int ret; 91 92 gpio_det = IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1); 93 gpio_wp = IOMUX_TO_GPIO(MX31_PIN_GPIO1_6); 94 95 mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, 96 MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); 97 mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, 98 MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); 99 mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, 100 MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); 101 mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, 102 MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); 103 mxc_iomux_set_pad(MX31_PIN_SD1_CMD, 104 MMC_PAD_CFG | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU); 105 mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG); 106 107 ret = gpio_request(gpio_det, "MMC detect"); 108 if (ret) 109 return ret; 110 111 ret = gpio_request(gpio_wp, "MMC w/p"); 112 if (ret) 113 goto exit_free_det; 114 115 gpio_direction_input(gpio_det); 116 gpio_direction_input(gpio_wp); 117 118 ret = request_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)), 119 detect_irq, 120 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 121 "MMC detect", data); 122 if (ret) 123 goto exit_free_wp; 124 125 return 0; 126 127exit_free_wp: 128 gpio_free(gpio_wp); 129 130exit_free_det: 131 gpio_free(gpio_det); 132 133 return ret; 134} 135 136static void mxc_mmc1_exit(struct device *dev, void *data) 137{ 138 gpio_free(gpio_det); 139 gpio_free(gpio_wp); 140 free_irq(gpio_to_irq(IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)), data); 141} 142 143static const struct imxmmc_platform_data mmc_pdata __initconst = { 144 .get_ro = mxc_mmc1_get_ro, 145 .init = mxc_mmc1_init, 146 .exit = mxc_mmc1_exit, 147}; 148 149/* SPI */ 150 151static int spi_internal_chipselect[] = { 152 MXC_SPI_CS(0), 153 MXC_SPI_CS(1), 154 MXC_SPI_CS(2), 155}; 156 157static const struct spi_imx_master spi0_pdata __initconst = { 158 .chipselect = spi_internal_chipselect, 159 .num_chipselect = ARRAY_SIZE(spi_internal_chipselect), 160}; 161 162/* GPIO LEDs */ 163 164static const struct gpio_led litekit_leds[] __initconst = { 165 { 166 .name = "GPIO0", 167 .gpio = IOMUX_TO_GPIO(MX31_PIN_COMPARE), 168 .active_low = 1, 169 .default_state = LEDS_GPIO_DEFSTATE_OFF, 170 }, 171 { 172 .name = "GPIO1", 173 .gpio = IOMUX_TO_GPIO(MX31_PIN_CAPTURE), 174 .active_low = 1, 175 .default_state = LEDS_GPIO_DEFSTATE_OFF, 176 } 177}; 178 179static const struct gpio_led_platform_data 180 litekit_led_platform_data __initconst = { 181 .leds = litekit_leds, 182 .num_leds = ARRAY_SIZE(litekit_leds), 183}; 184 185void __init mx31lite_db_init(void) 186{ 187 mxc_iomux_setup_multiple_pins(litekit_db_board_pins, 188 ARRAY_SIZE(litekit_db_board_pins), 189 "development board pins"); 190 imx31_add_imx_uart0(&uart_pdata); 191 imx31_add_mxc_mmc(0, &mmc_pdata); 192 imx31_add_spi_imx0(&spi0_pdata); 193 gpio_led_register_device(-1, &litekit_led_platform_data); 194 imx31_add_imx2_wdt(); 195 imx31_add_mxc_rtc(); 196} 197