1/* 2 * arch/arm/mach-pxa/colibri-pxa320.c 3 * 4 * Support for Toradex PXA320/310 based Colibri module 5 * 6 * Daniel Mack <daniel@caiaq.de> 7 * Matthias Meier <matthias.j.meier@gmx.net> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 */ 13 14#include <linux/init.h> 15#include <linux/kernel.h> 16#include <linux/platform_device.h> 17#include <linux/gpio.h> 18#include <linux/interrupt.h> 19#include <linux/usb/gpio_vbus.h> 20 21#include <asm/mach-types.h> 22#include <asm/sizes.h> 23#include <asm/mach/arch.h> 24#include <asm/mach/irq.h> 25 26#include <mach/pxa320.h> 27#include <mach/colibri.h> 28#include <linux/platform_data/video-pxafb.h> 29#include <linux/platform_data/usb-ohci-pxa27x.h> 30#include <mach/audio.h> 31#include <mach/pxa27x-udc.h> 32#include <mach/udc.h> 33 34#include "generic.h" 35#include "devices.h" 36 37#ifdef CONFIG_MACH_COLIBRI_EVALBOARD 38static mfp_cfg_t colibri_pxa320_evalboard_pin_config[] __initdata = { 39 /* MMC */ 40 GPIO22_MMC1_CLK, 41 GPIO23_MMC1_CMD, 42 GPIO18_MMC1_DAT0, 43 GPIO19_MMC1_DAT1, 44 GPIO20_MMC1_DAT2, 45 GPIO21_MMC1_DAT3, 46 GPIO28_GPIO, /* SD detect */ 47 48 /* UART 1 configuration (may be set by bootloader) */ 49 GPIO99_UART1_CTS, 50 GPIO104_UART1_RTS, 51 GPIO97_UART1_RXD, 52 GPIO98_UART1_TXD, 53 GPIO101_UART1_DTR, 54 GPIO103_UART1_DSR, 55 GPIO100_UART1_DCD, 56 GPIO102_UART1_RI, 57 58 /* UART 2 configuration */ 59 GPIO109_UART2_CTS, 60 GPIO112_UART2_RTS, 61 GPIO110_UART2_RXD, 62 GPIO111_UART2_TXD, 63 64 /* UART 3 configuration */ 65 GPIO30_UART3_RXD, 66 GPIO31_UART3_TXD, 67 68 /* UHC */ 69 GPIO2_2_USBH_PEN, 70 GPIO3_2_USBH_PWR, 71 72 /* I2C */ 73 GPIO32_I2C_SCL, 74 GPIO33_I2C_SDA, 75 76 /* PCMCIA */ 77 MFP_CFG(GPIO59, AF7), /* PRST ; AF7 to tristate */ 78 MFP_CFG(GPIO61, AF7), /* PCE1 ; AF7 to tristate */ 79 MFP_CFG(GPIO60, AF7), /* PCE2 ; AF7 to tristate */ 80 MFP_CFG(GPIO62, AF7), /* PCD ; AF7 to tristate */ 81 MFP_CFG(GPIO56, AF7), /* PSKTSEL ; AF7 to tristate */ 82 GPIO27_GPIO, /* RDnWR ; input/tristate */ 83 GPIO50_GPIO, /* PREG ; input/tristate */ 84 GPIO2_RDY, 85 GPIO5_NPIOR, 86 GPIO6_NPIOW, 87 GPIO7_NPIOS16, 88 GPIO8_NPWAIT, 89 GPIO29_GPIO, /* PRDY (READY GPIO) */ 90 GPIO57_GPIO, /* PPEN (POWER GPIO) */ 91 GPIO81_GPIO, /* PCD (DETECT GPIO) */ 92 GPIO77_GPIO, /* PRST (RESET GPIO) */ 93 GPIO53_GPIO, /* PBVD1 */ 94 GPIO79_GPIO, /* PBVD2 */ 95 GPIO54_GPIO, /* POE */ 96}; 97#else 98static mfp_cfg_t colibri_pxa320_evalboard_pin_config[] __initdata = {}; 99#endif 100 101#if defined(CONFIG_AX88796) 102#define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO36_GPIO) 103/* 104 * Asix AX88796 Ethernet 105 */ 106static struct ax_plat_data colibri_asix_platdata = { 107 .flags = 0, /* defined later */ 108 .wordlength = 2, 109}; 110 111static struct resource colibri_asix_resource[] = { 112 [0] = { 113 .start = PXA3xx_CS2_PHYS, 114 .end = PXA3xx_CS2_PHYS + (0x20 * 2) - 1, 115 .flags = IORESOURCE_MEM, 116 }, 117 [1] = { 118 .start = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO), 119 .end = PXA_GPIO_TO_IRQ(COLIBRI_ETH_IRQ_GPIO), 120 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, 121 } 122}; 123 124static struct platform_device asix_device = { 125 .name = "ax88796", 126 .id = 0, 127 .num_resources = ARRAY_SIZE(colibri_asix_resource), 128 .resource = colibri_asix_resource, 129 .dev = { 130 .platform_data = &colibri_asix_platdata 131 } 132}; 133 134static mfp_cfg_t colibri_pxa320_eth_pin_config[] __initdata = { 135 GPIO3_nCS2, /* AX88796 chip select */ 136 GPIO36_GPIO | MFP_PULL_HIGH /* AX88796 IRQ */ 137}; 138 139static void __init colibri_pxa320_init_eth(void) 140{ 141 colibri_pxa3xx_init_eth(&colibri_asix_platdata); 142 pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_eth_pin_config)); 143 platform_device_register(&asix_device); 144} 145#else 146static inline void __init colibri_pxa320_init_eth(void) {} 147#endif /* CONFIG_AX88796 */ 148 149#if defined(CONFIG_USB_PXA27X)||defined(CONFIG_USB_PXA27X_MODULE) 150static struct gpio_vbus_mach_info colibri_pxa320_gpio_vbus_info = { 151 .gpio_vbus = mfp_to_gpio(MFP_PIN_GPIO96), 152 .gpio_pullup = -1, 153}; 154 155static struct platform_device colibri_pxa320_gpio_vbus = { 156 .name = "gpio-vbus", 157 .id = -1, 158 .dev = { 159 .platform_data = &colibri_pxa320_gpio_vbus_info, 160 }, 161}; 162 163static void colibri_pxa320_udc_command(int cmd) 164{ 165 if (cmd == PXA2XX_UDC_CMD_CONNECT) 166 UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE; 167 else if (cmd == PXA2XX_UDC_CMD_DISCONNECT) 168 UP2OCR = UP2OCR_HXOE; 169} 170 171static struct pxa2xx_udc_mach_info colibri_pxa320_udc_info __initdata = { 172 .udc_command = colibri_pxa320_udc_command, 173 .gpio_pullup = -1, 174}; 175 176static void __init colibri_pxa320_init_udc(void) 177{ 178 pxa_set_udc_info(&colibri_pxa320_udc_info); 179 platform_device_register(&colibri_pxa320_gpio_vbus); 180} 181#else 182static inline void colibri_pxa320_init_udc(void) {} 183#endif 184 185#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) 186static mfp_cfg_t colibri_pxa320_lcd_pin_config[] __initdata = { 187 GPIO6_2_LCD_LDD_0, 188 GPIO7_2_LCD_LDD_1, 189 GPIO8_2_LCD_LDD_2, 190 GPIO9_2_LCD_LDD_3, 191 GPIO10_2_LCD_LDD_4, 192 GPIO11_2_LCD_LDD_5, 193 GPIO12_2_LCD_LDD_6, 194 GPIO13_2_LCD_LDD_7, 195 GPIO63_LCD_LDD_8, 196 GPIO64_LCD_LDD_9, 197 GPIO65_LCD_LDD_10, 198 GPIO66_LCD_LDD_11, 199 GPIO67_LCD_LDD_12, 200 GPIO68_LCD_LDD_13, 201 GPIO69_LCD_LDD_14, 202 GPIO70_LCD_LDD_15, 203 GPIO71_LCD_LDD_16, 204 GPIO72_LCD_LDD_17, 205 GPIO73_LCD_CS_N, 206 GPIO74_LCD_VSYNC, 207 GPIO14_2_LCD_FCLK, 208 GPIO15_2_LCD_LCLK, 209 GPIO16_2_LCD_PCLK, 210 GPIO17_2_LCD_BIAS, 211}; 212 213static void __init colibri_pxa320_init_lcd(void) 214{ 215 pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_lcd_pin_config)); 216} 217#else 218static inline void colibri_pxa320_init_lcd(void) {} 219#endif 220 221#if defined(CONFIG_SND_AC97_CODEC) || \ 222 defined(CONFIG_SND_AC97_CODEC_MODULE) 223static mfp_cfg_t colibri_pxa320_ac97_pin_config[] __initdata = { 224 GPIO34_AC97_SYSCLK, 225 GPIO35_AC97_SDATA_IN_0, 226 GPIO37_AC97_SDATA_OUT, 227 GPIO38_AC97_SYNC, 228 GPIO39_AC97_BITCLK, 229 GPIO40_AC97_nACRESET 230}; 231 232static inline void __init colibri_pxa320_init_ac97(void) 233{ 234 pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_ac97_pin_config)); 235 pxa_set_ac97_info(NULL); 236} 237#else 238static inline void colibri_pxa320_init_ac97(void) {} 239#endif 240 241void __init colibri_pxa320_init(void) 242{ 243 colibri_pxa320_init_eth(); 244 colibri_pxa3xx_init_nand(); 245 colibri_pxa320_init_lcd(); 246 colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO49_GPIO)); 247 colibri_pxa320_init_ac97(); 248 colibri_pxa320_init_udc(); 249 250 /* Evalboard init */ 251 pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_evalboard_pin_config)); 252 colibri_evalboard_init(); 253} 254 255MACHINE_START(COLIBRI320, "Toradex Colibri PXA320") 256 .atag_offset = 0x100, 257 .init_machine = colibri_pxa320_init, 258 .map_io = pxa3xx_map_io, 259 .nr_irqs = PXA_NR_IRQS, 260 .init_irq = pxa3xx_init_irq, 261 .handle_irq = pxa3xx_handle_irq, 262 .init_time = pxa_timer_init, 263 .restart = pxa_restart, 264MACHINE_END 265 266