| Daniel Mack | 1bc34f7 | 2009-05-20 19:54:34 +0200 | [diff] [blame] | 1 | /* | 
|  | 2 | *  LILLY-1131 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 | * You should have received a copy of the GNU General Public License | 
|  | 23 | * along with this program; if not, write to the Free Software | 
|  | 24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA | 
|  | 25 | */ | 
|  | 26 |  | 
|  | 27 | #include <linux/kernel.h> | 
|  | 28 | #include <linux/types.h> | 
|  | 29 | #include <linux/init.h> | 
| Daniel Mack | d0b1eab | 2009-05-20 19:54:36 +0200 | [diff] [blame] | 30 | #include <linux/gpio.h> | 
| Daniel Mack | b992387 | 2009-05-20 19:54:37 +0200 | [diff] [blame] | 31 | #include <linux/platform_device.h> | 
| Daniel Mack | 1bc34f7 | 2009-05-20 19:54:34 +0200 | [diff] [blame] | 32 |  | 
|  | 33 | #include <asm/mach-types.h> | 
|  | 34 | #include <asm/mach/arch.h> | 
|  | 35 | #include <asm/mach/map.h> | 
|  | 36 |  | 
|  | 37 | #include <mach/hardware.h> | 
|  | 38 | #include <mach/common.h> | 
|  | 39 | #include <mach/imx-uart.h> | 
|  | 40 | #include <mach/iomux-mx3.h> | 
|  | 41 | #include <mach/board-mx31lilly.h> | 
| Daniel Mack | d0b1eab | 2009-05-20 19:54:36 +0200 | [diff] [blame] | 42 | #include <mach/mmc.h> | 
| Daniel Mack | b992387 | 2009-05-20 19:54:37 +0200 | [diff] [blame] | 43 | #include <mach/mx3fb.h> | 
|  | 44 | #include <mach/ipu.h> | 
| Daniel Mack | 1bc34f7 | 2009-05-20 19:54:34 +0200 | [diff] [blame] | 45 |  | 
|  | 46 | #include "devices.h" | 
|  | 47 |  | 
|  | 48 | /* | 
|  | 49 | * This file contains board-specific initialization routines for the | 
|  | 50 | * LILLY-1131 development board. If you design an own baseboard for the | 
|  | 51 | * module, use this file as base for support code. | 
|  | 52 | */ | 
|  | 53 |  | 
|  | 54 | static unsigned int lilly_db_board_pins[] __initdata = { | 
|  | 55 | MX31_PIN_CTS1__CTS1, | 
|  | 56 | MX31_PIN_RTS1__RTS1, | 
|  | 57 | MX31_PIN_TXD1__TXD1, | 
|  | 58 | MX31_PIN_RXD1__RXD1, | 
| Daniel Mack | 8d9fb9b | 2009-05-31 12:57:22 +0200 | [diff] [blame] | 59 | MX31_PIN_CTS2__CTS2, | 
|  | 60 | MX31_PIN_RTS2__RTS2, | 
|  | 61 | MX31_PIN_TXD2__TXD2, | 
|  | 62 | MX31_PIN_RXD2__RXD2, | 
|  | 63 | MX31_PIN_CSPI3_MOSI__RXD3, | 
|  | 64 | MX31_PIN_CSPI3_MISO__TXD3, | 
|  | 65 | MX31_PIN_CSPI3_SCLK__RTS3, | 
|  | 66 | MX31_PIN_CSPI3_SPI_RDY__CTS3, | 
| Daniel Mack | d0b1eab | 2009-05-20 19:54:36 +0200 | [diff] [blame] | 67 | MX31_PIN_SD1_DATA3__SD1_DATA3, | 
|  | 68 | MX31_PIN_SD1_DATA2__SD1_DATA2, | 
|  | 69 | MX31_PIN_SD1_DATA1__SD1_DATA1, | 
|  | 70 | MX31_PIN_SD1_DATA0__SD1_DATA0, | 
|  | 71 | MX31_PIN_SD1_CLK__SD1_CLK, | 
|  | 72 | MX31_PIN_SD1_CMD__SD1_CMD, | 
| Daniel Mack | b992387 | 2009-05-20 19:54:37 +0200 | [diff] [blame] | 73 | MX31_PIN_LD0__LD0, | 
|  | 74 | MX31_PIN_LD1__LD1, | 
|  | 75 | MX31_PIN_LD2__LD2, | 
|  | 76 | MX31_PIN_LD3__LD3, | 
|  | 77 | MX31_PIN_LD4__LD4, | 
|  | 78 | MX31_PIN_LD5__LD5, | 
|  | 79 | MX31_PIN_LD6__LD6, | 
|  | 80 | MX31_PIN_LD7__LD7, | 
|  | 81 | MX31_PIN_LD8__LD8, | 
|  | 82 | MX31_PIN_LD9__LD9, | 
|  | 83 | MX31_PIN_LD10__LD10, | 
|  | 84 | MX31_PIN_LD11__LD11, | 
|  | 85 | MX31_PIN_LD12__LD12, | 
|  | 86 | MX31_PIN_LD13__LD13, | 
|  | 87 | MX31_PIN_LD14__LD14, | 
|  | 88 | MX31_PIN_LD15__LD15, | 
|  | 89 | MX31_PIN_LD16__LD16, | 
|  | 90 | MX31_PIN_LD17__LD17, | 
|  | 91 | MX31_PIN_VSYNC3__VSYNC3, | 
|  | 92 | MX31_PIN_HSYNC__HSYNC, | 
|  | 93 | MX31_PIN_FPSHIFT__FPSHIFT, | 
|  | 94 | MX31_PIN_DRDY0__DRDY0, | 
|  | 95 | MX31_PIN_CONTRAST__CONTRAST, | 
| Daniel Mack | 1bc34f7 | 2009-05-20 19:54:34 +0200 | [diff] [blame] | 96 | }; | 
|  | 97 |  | 
|  | 98 | /* UART */ | 
|  | 99 | static struct imxuart_platform_data uart_pdata __initdata = { | 
|  | 100 | .flags = IMXUART_HAVE_RTSCTS, | 
|  | 101 | }; | 
|  | 102 |  | 
| Daniel Mack | d0b1eab | 2009-05-20 19:54:36 +0200 | [diff] [blame] | 103 | /* MMC support */ | 
|  | 104 |  | 
|  | 105 | static int mxc_mmc1_get_ro(struct device *dev) | 
|  | 106 | { | 
|  | 107 | return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_LCS0)); | 
|  | 108 | } | 
|  | 109 |  | 
|  | 110 | static int gpio_det, gpio_wp; | 
|  | 111 |  | 
| Daniel Mack | 24fb842 | 2009-10-26 11:55:58 +0100 | [diff] [blame] | 112 | #define MMC_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \ | 
|  | 113 | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU) | 
|  | 114 |  | 
| Daniel Mack | d0b1eab | 2009-05-20 19:54:36 +0200 | [diff] [blame] | 115 | static int mxc_mmc1_init(struct device *dev, | 
|  | 116 | irq_handler_t detect_irq, void *data) | 
|  | 117 | { | 
|  | 118 | int ret; | 
|  | 119 |  | 
|  | 120 | gpio_det = IOMUX_TO_GPIO(MX31_PIN_GPIO1_1); | 
|  | 121 | gpio_wp = IOMUX_TO_GPIO(MX31_PIN_LCS0); | 
|  | 122 |  | 
| Daniel Mack | 24fb842 | 2009-10-26 11:55:58 +0100 | [diff] [blame] | 123 | mxc_iomux_set_pad(MX31_PIN_SD1_DATA0, MMC_PAD_CFG); | 
|  | 124 | mxc_iomux_set_pad(MX31_PIN_SD1_DATA1, MMC_PAD_CFG); | 
|  | 125 | mxc_iomux_set_pad(MX31_PIN_SD1_DATA2, MMC_PAD_CFG); | 
|  | 126 | mxc_iomux_set_pad(MX31_PIN_SD1_DATA3, MMC_PAD_CFG); | 
|  | 127 | mxc_iomux_set_pad(MX31_PIN_SD1_CLK, MMC_PAD_CFG); | 
|  | 128 | mxc_iomux_set_pad(MX31_PIN_SD1_CMD, MMC_PAD_CFG); | 
|  | 129 |  | 
| Daniel Mack | d0b1eab | 2009-05-20 19:54:36 +0200 | [diff] [blame] | 130 | ret = gpio_request(gpio_det, "MMC detect"); | 
|  | 131 | if (ret) | 
|  | 132 | return ret; | 
|  | 133 |  | 
|  | 134 | ret = gpio_request(gpio_wp, "MMC w/p"); | 
|  | 135 | if (ret) | 
|  | 136 | goto exit_free_det; | 
|  | 137 |  | 
|  | 138 | gpio_direction_input(gpio_det); | 
|  | 139 | gpio_direction_input(gpio_wp); | 
|  | 140 |  | 
|  | 141 | ret = request_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), detect_irq, | 
|  | 142 | IRQF_DISABLED | IRQF_TRIGGER_FALLING, | 
|  | 143 | "MMC detect", data); | 
|  | 144 | if (ret) | 
|  | 145 | goto exit_free_wp; | 
|  | 146 |  | 
|  | 147 | return 0; | 
|  | 148 |  | 
|  | 149 | exit_free_wp: | 
|  | 150 | gpio_free(gpio_wp); | 
|  | 151 |  | 
|  | 152 | exit_free_det: | 
|  | 153 | gpio_free(gpio_det); | 
|  | 154 |  | 
|  | 155 | return ret; | 
|  | 156 | } | 
|  | 157 |  | 
|  | 158 | static void mxc_mmc1_exit(struct device *dev, void *data) | 
|  | 159 | { | 
|  | 160 | gpio_free(gpio_det); | 
|  | 161 | gpio_free(gpio_wp); | 
|  | 162 | free_irq(IOMUX_TO_IRQ(MX31_PIN_GPIO1_1), data); | 
|  | 163 | } | 
|  | 164 |  | 
|  | 165 | static struct imxmmc_platform_data mmc_pdata = { | 
|  | 166 | .get_ro	= mxc_mmc1_get_ro, | 
|  | 167 | .init	= mxc_mmc1_init, | 
|  | 168 | .exit	= mxc_mmc1_exit, | 
|  | 169 | }; | 
|  | 170 |  | 
| Daniel Mack | b992387 | 2009-05-20 19:54:37 +0200 | [diff] [blame] | 171 | /* Framebuffer support */ | 
|  | 172 | static struct ipu_platform_data ipu_data __initdata = { | 
|  | 173 | .irq_base = MXC_IPU_IRQ_START, | 
|  | 174 | }; | 
|  | 175 |  | 
|  | 176 | static const struct fb_videomode fb_modedb = { | 
|  | 177 | /* 640x480 TFT panel (IPS-056T) */ | 
|  | 178 | .name	   	= "CRT-VGA", | 
|  | 179 | .refresh	= 64, | 
|  | 180 | .xres		= 640, | 
|  | 181 | .yres		= 480, | 
|  | 182 | .pixclock	= 30000, | 
|  | 183 | .left_margin	= 200, | 
|  | 184 | .right_margin	= 2, | 
|  | 185 | .upper_margin	= 2, | 
|  | 186 | .lower_margin	= 2, | 
|  | 187 | .hsync_len	= 3, | 
|  | 188 | .vsync_len	= 1, | 
|  | 189 | .sync		= FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, | 
|  | 190 | .vmode		= FB_VMODE_NONINTERLACED, | 
|  | 191 | .flag		= 0, | 
|  | 192 | }; | 
|  | 193 |  | 
|  | 194 | static struct mx3fb_platform_data fb_pdata __initdata = { | 
|  | 195 | .dma_dev	= &mx3_ipu.dev, | 
|  | 196 | .name		= "CRT-VGA", | 
|  | 197 | .mode		= &fb_modedb, | 
|  | 198 | .num_modes	= 1, | 
|  | 199 | }; | 
|  | 200 |  | 
|  | 201 | #define LCD_VCC_EN_GPIO	 (7) | 
|  | 202 |  | 
|  | 203 | static void __init mx31lilly_init_fb(void) | 
|  | 204 | { | 
|  | 205 | if (gpio_request(LCD_VCC_EN_GPIO, "LCD enable") != 0) { | 
|  | 206 | printk(KERN_WARNING "unable to request LCD_VCC_EN pin.\n"); | 
|  | 207 | return; | 
|  | 208 | } | 
|  | 209 |  | 
|  | 210 | mxc_register_device(&mx3_ipu, &ipu_data); | 
|  | 211 | mxc_register_device(&mx3_fb, &fb_pdata); | 
|  | 212 | gpio_direction_output(LCD_VCC_EN_GPIO, 1); | 
|  | 213 | } | 
|  | 214 |  | 
| Daniel Mack | 1bc34f7 | 2009-05-20 19:54:34 +0200 | [diff] [blame] | 215 | void __init mx31lilly_db_init(void) | 
|  | 216 | { | 
|  | 217 | mxc_iomux_setup_multiple_pins(lilly_db_board_pins, | 
|  | 218 | ARRAY_SIZE(lilly_db_board_pins), | 
|  | 219 | "development board pins"); | 
|  | 220 | mxc_register_device(&mxc_uart_device0, &uart_pdata); | 
| Daniel Mack | 8d9fb9b | 2009-05-31 12:57:22 +0200 | [diff] [blame] | 221 | mxc_register_device(&mxc_uart_device1, &uart_pdata); | 
|  | 222 | mxc_register_device(&mxc_uart_device2, &uart_pdata); | 
| Daniel Mack | d0b1eab | 2009-05-20 19:54:36 +0200 | [diff] [blame] | 223 | mxc_register_device(&mxcsdhc_device0, &mmc_pdata); | 
| Daniel Mack | b992387 | 2009-05-20 19:54:37 +0200 | [diff] [blame] | 224 | mx31lilly_init_fb(); | 
| Daniel Mack | 1bc34f7 | 2009-05-20 19:54:34 +0200 | [diff] [blame] | 225 | } | 
|  | 226 |  |