1/* 2 * linux/arch/arm/mach-pxa/cm-x270.c 3 * 4 * Copyright (C) 2007, 2008 CompuLab, Ltd. 5 * Mike Rapoport <mike@compulab.co.il> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12#include <linux/platform_device.h> 13#include <linux/sysdev.h> 14#include <linux/irq.h> 15#include <linux/gpio.h> 16#include <linux/delay.h> 17 18#include <linux/rtc-v3020.h> 19#include <video/mbxfb.h> 20 21#include <linux/spi/spi.h> 22#include <linux/spi/libertas_spi.h> 23 24#include <mach/pxa27x.h> 25#include <mach/ohci.h> 26#include <mach/mmc.h> 27#include <mach/pxa2xx_spi.h> 28 29#include "generic.h" 30 31/* physical address if local-bus attached devices */ 32#define RTC_PHYS_BASE (PXA_CS1_PHYS + (5 << 22)) 33 34/* GPIO IRQ usage */ 35#define GPIO83_MMC_IRQ (83) 36 37#define CMX270_MMC_IRQ IRQ_GPIO(GPIO83_MMC_IRQ) 38 39/* MMC power enable */ 40#define GPIO105_MMC_POWER (105) 41 42/* WLAN GPIOS */ 43#define GPIO19_WLAN_STRAP (19) 44#define GPIO102_WLAN_RST (102) 45 46static unsigned long cmx270_pin_config[] = { 47 /* AC'97 */ 48 GPIO28_AC97_BITCLK, 49 GPIO29_AC97_SDATA_IN_0, 50 GPIO30_AC97_SDATA_OUT, 51 GPIO31_AC97_SYNC, 52 GPIO98_AC97_SYSCLK, 53 GPIO113_AC97_nRESET, 54 55 /* BTUART */ 56 GPIO42_BTUART_RXD, 57 GPIO43_BTUART_TXD, 58 GPIO44_BTUART_CTS, 59 GPIO45_BTUART_RTS, 60 61 /* STUART */ 62 GPIO46_STUART_RXD, 63 GPIO47_STUART_TXD, 64 65 /* MCI controller */ 66 GPIO32_MMC_CLK, 67 GPIO112_MMC_CMD, 68 GPIO92_MMC_DAT_0, 69 GPIO109_MMC_DAT_1, 70 GPIO110_MMC_DAT_2, 71 GPIO111_MMC_DAT_3, 72 73 /* LCD */ 74 GPIOxx_LCD_TFT_16BPP, 75 76 /* I2C */ 77 GPIO117_I2C_SCL, 78 GPIO118_I2C_SDA, 79 80 /* SSP1 */ 81 GPIO23_SSP1_SCLK, 82 GPIO24_SSP1_SFRM, 83 GPIO25_SSP1_TXD, 84 GPIO26_SSP1_RXD, 85 86 /* SSP2 */ 87 GPIO19_GPIO, /* SSP2 clock is used as GPIO for Libertas pin-strap */ 88 GPIO14_GPIO, 89 GPIO87_SSP2_TXD, 90 GPIO88_SSP2_RXD, 91 92 /* PC Card */ 93 GPIO48_nPOE, 94 GPIO49_nPWE, 95 GPIO50_nPIOR, 96 GPIO51_nPIOW, 97 GPIO85_nPCE_1, 98 GPIO54_nPCE_2, 99 GPIO55_nPREG, 100 GPIO56_nPWAIT, 101 GPIO57_nIOIS16, 102 103 /* SDRAM and local bus */ 104 GPIO15_nCS_1, 105 GPIO78_nCS_2, 106 GPIO79_nCS_3, 107 GPIO80_nCS_4, 108 GPIO33_nCS_5, 109 GPIO49_nPWE, 110 GPIO18_RDY, 111 112 /* GPIO */ 113 GPIO0_GPIO | WAKEUP_ON_EDGE_BOTH, 114 GPIO105_GPIO | MFP_LPM_DRIVE_HIGH, /* MMC/SD power */ 115 GPIO53_GPIO, /* PC card reset */ 116 GPIO102_GPIO, /* WLAN reset */ 117 118 /* NAND controls */ 119 GPIO11_GPIO | MFP_LPM_DRIVE_HIGH, /* NAND CE# */ 120 GPIO89_GPIO, /* NAND Ready/Busy */ 121 122 /* interrupts */ 123 GPIO10_GPIO, /* DM9000 interrupt */ 124 GPIO83_GPIO, /* MMC card detect */ 125 GPIO95_GPIO, /* WLAN interrupt */ 126}; 127 128/* V3020 RTC */ 129#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE) 130static struct resource cmx270_v3020_resource[] = { 131 [0] = { 132 .start = RTC_PHYS_BASE, 133 .end = RTC_PHYS_BASE + 4, 134 .flags = IORESOURCE_MEM, 135 }, 136}; 137 138struct v3020_platform_data cmx270_v3020_pdata = { 139 .leftshift = 16, 140}; 141 142static struct platform_device cmx270_rtc_device = { 143 .name = "v3020", 144 .num_resources = ARRAY_SIZE(cmx270_v3020_resource), 145 .resource = cmx270_v3020_resource, 146 .id = -1, 147 .dev = { 148 .platform_data = &cmx270_v3020_pdata, 149 } 150}; 151 152static void __init cmx270_init_rtc(void) 153{ 154 platform_device_register(&cmx270_rtc_device); 155} 156#else 157static inline void cmx270_init_rtc(void) {} 158#endif 159 160/* 2700G graphics */ 161#if defined(CONFIG_FB_MBX) || defined(CONFIG_FB_MBX_MODULE) 162static u64 fb_dma_mask = ~(u64)0; 163 164static struct resource cmx270_2700G_resource[] = { 165 /* frame buffer memory including ODFB and External SDRAM */ 166 [0] = { 167 .start = PXA_CS2_PHYS, 168 .end = PXA_CS2_PHYS + 0x01ffffff, 169 .flags = IORESOURCE_MEM, 170 }, 171 /* Marathon registers */ 172 [1] = { 173 .start = PXA_CS2_PHYS + 0x03fe0000, 174 .end = PXA_CS2_PHYS + 0x03ffffff, 175 .flags = IORESOURCE_MEM, 176 }, 177}; 178 179static unsigned long cmx270_marathon_on[] = { 180 GPIO58_GPIO, 181 GPIO59_GPIO, 182 GPIO60_GPIO, 183 GPIO61_GPIO, 184 GPIO62_GPIO, 185 GPIO63_GPIO, 186 GPIO64_GPIO, 187 GPIO65_GPIO, 188 GPIO66_GPIO, 189 GPIO67_GPIO, 190 GPIO68_GPIO, 191 GPIO69_GPIO, 192 GPIO70_GPIO, 193 GPIO71_GPIO, 194 GPIO72_GPIO, 195 GPIO73_GPIO, 196 GPIO74_GPIO, 197 GPIO75_GPIO, 198 GPIO76_GPIO, 199 GPIO77_GPIO, 200}; 201 202static unsigned long cmx270_marathon_off[] = { 203 GPIOxx_LCD_TFT_16BPP, 204}; 205 206static int cmx270_marathon_probe(struct fb_info *fb) 207{ 208 int gpio, err; 209 210 for (gpio = 58; gpio <= 77; gpio++) { 211 err = gpio_request(gpio, "LCD"); 212 if (err) 213 return err; 214 gpio_direction_input(gpio); 215 } 216 217 pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_marathon_on)); 218 return 0; 219} 220 221static int cmx270_marathon_remove(struct fb_info *fb) 222{ 223 int gpio; 224 225 pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_marathon_off)); 226 227 for (gpio = 58; gpio <= 77; gpio++) 228 gpio_free(gpio); 229 230 return 0; 231} 232 233static struct mbxfb_platform_data cmx270_2700G_data = { 234 .xres = { 235 .min = 240, 236 .max = 1200, 237 .defval = 640, 238 }, 239 .yres = { 240 .min = 240, 241 .max = 1200, 242 .defval = 480, 243 }, 244 .bpp = { 245 .min = 16, 246 .max = 32, 247 .defval = 16, 248 }, 249 .memsize = 8*1024*1024, 250 .probe = cmx270_marathon_probe, 251 .remove = cmx270_marathon_remove, 252}; 253 254static struct platform_device cmx270_2700G = { 255 .name = "mbx-fb", 256 .dev = { 257 .platform_data = &cmx270_2700G_data, 258 .dma_mask = &fb_dma_mask, 259 .coherent_dma_mask = 0xffffffff, 260 }, 261 .num_resources = ARRAY_SIZE(cmx270_2700G_resource), 262 .resource = cmx270_2700G_resource, 263 .id = -1, 264}; 265 266static void __init cmx270_init_2700G(void) 267{ 268 platform_device_register(&cmx270_2700G); 269} 270#else 271static inline void cmx270_init_2700G(void) {} 272#endif 273 274/* PXA27x OHCI controller setup */ 275#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 276static struct pxaohci_platform_data cmx270_ohci_platform_data = { 277 .port_mode = PMM_PERPORT_MODE, 278 .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW, 279}; 280 281static void __init cmx270_init_ohci(void) 282{ 283 pxa_set_ohci_info(&cmx270_ohci_platform_data); 284} 285#else 286static inline void cmx270_init_ohci(void) {} 287#endif 288 289#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) 290static struct pxamci_platform_data cmx270_mci_platform_data = { 291 .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, 292 .gpio_card_detect = GPIO83_MMC_IRQ, 293 .gpio_card_ro = -1, 294 .gpio_power = GPIO105_MMC_POWER, 295 .gpio_power_invert = 1, 296}; 297 298static void __init cmx270_init_mmc(void) 299{ 300 pxa_set_mci_info(&cmx270_mci_platform_data); 301} 302#else 303static inline void cmx270_init_mmc(void) {} 304#endif 305 306#if defined(CONFIG_SPI_PXA2XX) || defined(CONFIG_SPI_PXA2XX_MODULE) 307static struct pxa2xx_spi_master cm_x270_spi_info = { 308 .num_chipselect = 1, 309 .enable_dma = 1, 310}; 311 312static struct pxa2xx_spi_chip cm_x270_libertas_chip = { 313 .rx_threshold = 1, 314 .tx_threshold = 1, 315 .timeout = 1000, 316 .gpio_cs = 14, 317}; 318 319static unsigned long cm_x270_libertas_pin_config[] = { 320 /* SSP2 */ 321 GPIO19_SSP2_SCLK, 322 GPIO14_GPIO, 323 GPIO87_SSP2_TXD, 324 GPIO88_SSP2_RXD, 325 326}; 327 328static int cm_x270_libertas_setup(struct spi_device *spi) 329{ 330 int err = gpio_request(GPIO19_WLAN_STRAP, "WLAN STRAP"); 331 if (err) 332 return err; 333 334 err = gpio_request(GPIO102_WLAN_RST, "WLAN RST"); 335 if (err) 336 goto err_free_strap; 337 338 err = gpio_direction_output(GPIO102_WLAN_RST, 0); 339 if (err) 340 goto err_free_strap; 341 msleep(100); 342 343 err = gpio_direction_output(GPIO19_WLAN_STRAP, 1); 344 if (err) 345 goto err_free_strap; 346 msleep(100); 347 348 pxa2xx_mfp_config(ARRAY_AND_SIZE(cm_x270_libertas_pin_config)); 349 350 gpio_set_value(GPIO102_WLAN_RST, 1); 351 msleep(100); 352 353 spi->bits_per_word = 16; 354 spi_setup(spi); 355 356 return 0; 357 358err_free_strap: 359 gpio_free(GPIO19_WLAN_STRAP); 360 361 return err; 362} 363 364static int cm_x270_libertas_teardown(struct spi_device *spi) 365{ 366 gpio_set_value(GPIO102_WLAN_RST, 0); 367 gpio_free(GPIO102_WLAN_RST); 368 gpio_free(GPIO19_WLAN_STRAP); 369 370 return 0; 371} 372 373struct libertas_spi_platform_data cm_x270_libertas_pdata = { 374 .use_dummy_writes = 1, 375 .setup = cm_x270_libertas_setup, 376 .teardown = cm_x270_libertas_teardown, 377}; 378 379static struct spi_board_info cm_x270_spi_devices[] __initdata = { 380 { 381 .modalias = "libertas_spi", 382 .max_speed_hz = 13000000, 383 .bus_num = 2, 384 .irq = gpio_to_irq(95), 385 .chip_select = 0, 386 .controller_data = &cm_x270_libertas_chip, 387 .platform_data = &cm_x270_libertas_pdata, 388 }, 389}; 390 391static void __init cmx270_init_spi(void) 392{ 393 pxa2xx_set_spi_info(2, &cm_x270_spi_info); 394 spi_register_board_info(ARRAY_AND_SIZE(cm_x270_spi_devices)); 395} 396#else 397static inline void cmx270_init_spi(void) {} 398#endif 399 400void __init cmx270_init(void) 401{ 402 pxa2xx_mfp_config(ARRAY_AND_SIZE(cmx270_pin_config)); 403 404#ifdef CONFIG_PM 405 pxa27x_set_pwrmode(PWRMODE_DEEPSLEEP); 406#endif 407 408 cmx270_init_rtc(); 409 cmx270_init_mmc(); 410 cmx270_init_ohci(); 411 cmx270_init_2700G(); 412 cmx270_init_spi(); 413} 414