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/pxa3xx-regs.h> 27#include <mach/mfp-pxa320.h> 28#include <mach/colibri.h> 29#include <mach/pxafb.h> 30#include <mach/ohci.h> 31#include <mach/audio.h> 32#include <mach/pxa27x-udc.h> 33#include <mach/udc.h> 34 35#include "generic.h" 36#include "devices.h" 37 38#if defined(CONFIG_AX88796) 39#define COLIBRI_ETH_IRQ_GPIO mfp_to_gpio(GPIO36_GPIO) 40 41/* 42 * Asix AX88796 Ethernet 43 */ 44static struct ax_plat_data colibri_asix_platdata = { 45 .flags = 0, /* defined later */ 46 .wordlength = 2, 47}; 48 49static struct resource colibri_asix_resource[] = { 50 [0] = { 51 .start = PXA3xx_CS2_PHYS, 52 .end = PXA3xx_CS2_PHYS + (0x20 * 2) - 1, 53 .flags = IORESOURCE_MEM, 54 }, 55 [1] = { 56 .start = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), 57 .end = gpio_to_irq(COLIBRI_ETH_IRQ_GPIO), 58 .flags = IORESOURCE_IRQ | IRQF_TRIGGER_FALLING, 59 } 60}; 61 62static struct platform_device asix_device = { 63 .name = "ax88796", 64 .id = 0, 65 .num_resources = ARRAY_SIZE(colibri_asix_resource), 66 .resource = colibri_asix_resource, 67 .dev = { 68 .platform_data = &colibri_asix_platdata 69 } 70}; 71 72static mfp_cfg_t colibri_pxa320_eth_pin_config[] __initdata = { 73 GPIO3_nCS2, /* AX88796 chip select */ 74 GPIO36_GPIO | MFP_PULL_HIGH /* AX88796 IRQ */ 75}; 76 77static void __init colibri_pxa320_init_eth(void) 78{ 79 colibri_pxa3xx_init_eth(&colibri_asix_platdata); 80 pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_eth_pin_config)); 81 platform_device_register(&asix_device); 82} 83#else 84static inline void __init colibri_pxa320_init_eth(void) {} 85#endif /* CONFIG_AX88796 */ 86 87#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 88static mfp_cfg_t colibri_pxa320_usb_pin_config[] __initdata = { 89 GPIO2_2_USBH_PEN, 90 GPIO3_2_USBH_PWR, 91}; 92 93static struct pxaohci_platform_data colibri_pxa320_ohci_info = { 94 .port_mode = PMM_GLOBAL_MODE, 95 .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | POWER_SENSE_LOW, 96}; 97 98void __init colibri_pxa320_init_ohci(void) 99{ 100 pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_usb_pin_config)); 101 pxa_set_ohci_info(&colibri_pxa320_ohci_info); 102} 103#else 104static inline void colibri_pxa320_init_ohci(void) {} 105#endif /* CONFIG_USB_OHCI_HCD || CONFIG_USB_OHCI_HCD_MODULE */ 106 107#if defined(CONFIG_USB_GADGET_PXA27X)||defined(CONFIG_USB_GADGET_PXA27X_MODULE) 108static struct gpio_vbus_mach_info colibri_pxa320_gpio_vbus_info = { 109 .gpio_vbus = mfp_to_gpio(MFP_PIN_GPIO96), 110 .gpio_pullup = -1, 111}; 112 113static struct platform_device colibri_pxa320_gpio_vbus = { 114 .name = "gpio-vbus", 115 .id = -1, 116 .dev = { 117 .platform_data = &colibri_pxa320_gpio_vbus_info, 118 }, 119}; 120 121static void colibri_pxa320_udc_command(int cmd) 122{ 123 if (cmd == PXA2XX_UDC_CMD_CONNECT) 124 UP2OCR = UP2OCR_HXOE | UP2OCR_DPPUE; 125 else if (cmd == PXA2XX_UDC_CMD_DISCONNECT) 126 UP2OCR = UP2OCR_HXOE; 127} 128 129static struct pxa2xx_udc_mach_info colibri_pxa320_udc_info __initdata = { 130 .udc_command = colibri_pxa320_udc_command, 131 .gpio_pullup = -1, 132}; 133 134static void __init colibri_pxa320_init_udc(void) 135{ 136 pxa_set_udc_info(&colibri_pxa320_udc_info); 137 platform_device_register(&colibri_pxa320_gpio_vbus); 138} 139#else 140static inline void colibri_pxa320_init_udc(void) {} 141#endif 142 143static mfp_cfg_t colibri_pxa320_mmc_pin_config[] __initdata = { 144 GPIO22_MMC1_CLK, 145 GPIO23_MMC1_CMD, 146 GPIO18_MMC1_DAT0, 147 GPIO19_MMC1_DAT1, 148 GPIO20_MMC1_DAT2, 149 GPIO21_MMC1_DAT3 150}; 151 152#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) 153static mfp_cfg_t colibri_pxa320_lcd_pin_config[] __initdata = { 154 GPIO6_2_LCD_LDD_0, 155 GPIO7_2_LCD_LDD_1, 156 GPIO8_2_LCD_LDD_2, 157 GPIO9_2_LCD_LDD_3, 158 GPIO10_2_LCD_LDD_4, 159 GPIO11_2_LCD_LDD_5, 160 GPIO12_2_LCD_LDD_6, 161 GPIO13_2_LCD_LDD_7, 162 GPIO63_LCD_LDD_8, 163 GPIO64_LCD_LDD_9, 164 GPIO65_LCD_LDD_10, 165 GPIO66_LCD_LDD_11, 166 GPIO67_LCD_LDD_12, 167 GPIO68_LCD_LDD_13, 168 GPIO69_LCD_LDD_14, 169 GPIO70_LCD_LDD_15, 170 GPIO71_LCD_LDD_16, 171 GPIO72_LCD_LDD_17, 172 GPIO73_LCD_CS_N, 173 GPIO74_LCD_VSYNC, 174 GPIO14_2_LCD_FCLK, 175 GPIO15_2_LCD_LCLK, 176 GPIO16_2_LCD_PCLK, 177 GPIO17_2_LCD_BIAS, 178}; 179 180static void __init colibri_pxa320_init_lcd(void) 181{ 182 pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_lcd_pin_config)); 183} 184#else 185static inline void colibri_pxa320_init_lcd(void) {} 186#endif 187 188#if defined(CONFIG_SND_AC97_CODEC) || defined(CONFIG_SND_AC97_CODEC_MODULE) 189static mfp_cfg_t colibri_pxa320_ac97_pin_config[] __initdata = { 190 GPIO34_AC97_SYSCLK, 191 GPIO35_AC97_SDATA_IN_0, 192 GPIO37_AC97_SDATA_OUT, 193 GPIO38_AC97_SYNC, 194 GPIO39_AC97_BITCLK, 195 GPIO40_AC97_nACRESET 196}; 197 198static inline void __init colibri_pxa320_init_ac97(void) 199{ 200 pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_ac97_pin_config)); 201 pxa_set_ac97_info(NULL); 202} 203#else 204static inline void colibri_pxa320_init_ac97(void) {} 205#endif 206 207/* 208 * The following configuration is verified to work with the Toradex Orchid 209 * carrier board 210 */ 211static mfp_cfg_t colibri_pxa320_uart_pin_config[] __initdata = { 212 /* UART 1 configuration (may be set by bootloader) */ 213 GPIO99_UART1_CTS, 214 GPIO104_UART1_RTS, 215 GPIO97_UART1_RXD, 216 GPIO98_UART1_TXD, 217 GPIO101_UART1_DTR, 218 GPIO103_UART1_DSR, 219 GPIO100_UART1_DCD, 220 GPIO102_UART1_RI, 221 222 /* UART 2 configuration */ 223 GPIO109_UART2_CTS, 224 GPIO112_UART2_RTS, 225 GPIO110_UART2_RXD, 226 GPIO111_UART2_TXD, 227 228 /* UART 3 configuration */ 229 GPIO30_UART3_RXD, 230 GPIO31_UART3_TXD, 231}; 232 233static void __init colibri_pxa320_init_uart(void) 234{ 235 pxa3xx_mfp_config(ARRAY_AND_SIZE(colibri_pxa320_uart_pin_config)); 236} 237 238void __init colibri_pxa320_init(void) 239{ 240 pxa_set_ffuart_info(NULL); 241 pxa_set_btuart_info(NULL); 242 pxa_set_stuart_info(NULL); 243 244 colibri_pxa320_init_eth(); 245 colibri_pxa320_init_ohci(); 246 colibri_pxa3xx_init_nand(); 247 colibri_pxa320_init_lcd(); 248 colibri_pxa3xx_init_lcd(mfp_to_gpio(GPIO49_GPIO)); 249 colibri_pxa320_init_ac97(); 250 colibri_pxa3xx_init_mmc(ARRAY_AND_SIZE(colibri_pxa320_mmc_pin_config), 251 mfp_to_gpio(MFP_PIN_GPIO28)); 252 colibri_pxa320_init_uart(); 253 colibri_pxa320_init_udc(); 254} 255 256MACHINE_START(COLIBRI320, "Toradex Colibri PXA320") 257 .phys_io = 0x40000000, 258 .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, 259 .boot_params = COLIBRI_SDRAM_BASE + 0x100, 260 .init_machine = colibri_pxa320_init, 261 .map_io = pxa_map_io, 262 .init_irq = pxa3xx_init_irq, 263 .timer = &pxa_timer, 264MACHINE_END 265