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