1/* 2 * linux/arch/arm/mach-omap1/board-voiceblue.c 3 * 4 * Modified from board-generic.c 5 * 6 * Copyright (C) 2004 2N Telekomunikace, Ladislav Michl <michl@2n.cz> 7 * 8 * Code for OMAP5910 based VoiceBlue board (VoIP to GSM gateway). 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15#include <linux/delay.h> 16#include <linux/platform_device.h> 17#include <linux/interrupt.h> 18#include <linux/init.h> 19#include <linux/kernel.h> 20#include <linux/notifier.h> 21#include <linux/reboot.h> 22#include <linux/serial_8250.h> 23#include <linux/serial_reg.h> 24 25#include <asm/hardware.h> 26#include <asm/mach-types.h> 27#include <asm/mach/arch.h> 28#include <asm/mach/flash.h> 29#include <asm/mach/map.h> 30 31#include <asm/arch/common.h> 32#include <asm/arch/gpio.h> 33#include <asm/arch/mux.h> 34#include <asm/arch/tc.h> 35#include <asm/arch/usb.h> 36 37extern void omap_init_time(void); 38extern int omap_gpio_init(void); 39 40static struct plat_serial8250_port voiceblue_ports[] = { 41 { 42 .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x40000), 43 .irq = OMAP_GPIO_IRQ(12), 44 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, 45 .iotype = UPIO_MEM, 46 .regshift = 1, 47 .uartclk = 3686400, 48 }, 49 { 50 .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x50000), 51 .irq = OMAP_GPIO_IRQ(13), 52 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, 53 .iotype = UPIO_MEM, 54 .regshift = 1, 55 .uartclk = 3686400, 56 }, 57 { 58 .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x60000), 59 .irq = OMAP_GPIO_IRQ(14), 60 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, 61 .iotype = UPIO_MEM, 62 .regshift = 1, 63 .uartclk = 3686400, 64 }, 65 { 66 .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x70000), 67 .irq = OMAP_GPIO_IRQ(15), 68 .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, 69 .iotype = UPIO_MEM, 70 .regshift = 1, 71 .uartclk = 3686400, 72 }, 73 { }, 74}; 75 76static struct platform_device serial_device = { 77 .name = "serial8250", 78 .id = PLAT8250_DEV_PLATFORM1, 79 .dev = { 80 .platform_data = voiceblue_ports, 81 }, 82}; 83 84static int __init ext_uart_init(void) 85{ 86 return platform_device_register(&serial_device); 87} 88arch_initcall(ext_uart_init); 89 90static struct flash_platform_data voiceblue_flash_data = { 91 .map_name = "cfi_probe", 92 .width = 2, 93}; 94 95static struct resource voiceblue_flash_resource = { 96 .start = OMAP_CS0_PHYS, 97 .end = OMAP_CS0_PHYS + SZ_32M - 1, 98 .flags = IORESOURCE_MEM, 99}; 100 101static struct platform_device voiceblue_flash_device = { 102 .name = "omapflash", 103 .id = 0, 104 .dev = { 105 .platform_data = &voiceblue_flash_data, 106 }, 107 .num_resources = 1, 108 .resource = &voiceblue_flash_resource, 109}; 110 111static struct resource voiceblue_smc91x_resources[] = { 112 [0] = { 113 .start = OMAP_CS2_PHYS + 0x300, 114 .end = OMAP_CS2_PHYS + 0x300 + 16, 115 .flags = IORESOURCE_MEM, 116 }, 117 [1] = { 118 .start = OMAP_GPIO_IRQ(8), 119 .end = OMAP_GPIO_IRQ(8), 120 .flags = IORESOURCE_IRQ, 121 }, 122}; 123 124static struct platform_device voiceblue_smc91x_device = { 125 .name = "smc91x", 126 .id = 0, 127 .num_resources = ARRAY_SIZE(voiceblue_smc91x_resources), 128 .resource = voiceblue_smc91x_resources, 129}; 130 131static struct platform_device *voiceblue_devices[] __initdata = { 132 &voiceblue_flash_device, 133 &voiceblue_smc91x_device, 134}; 135 136static struct omap_usb_config voiceblue_usb_config __initdata = { 137 .hmc_mode = 3, 138 .register_host = 1, 139 .register_dev = 1, 140 .pins[0] = 2, 141 .pins[1] = 6, 142 .pins[2] = 6, 143}; 144 145static struct omap_mmc_config voiceblue_mmc_config __initdata = { 146 .mmc[0] = { 147 .enabled = 1, 148 .power_pin = 2, 149 .switch_pin = -1, 150 }, 151}; 152 153static struct omap_uart_config voiceblue_uart_config __initdata = { 154 .enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)), 155}; 156 157static struct omap_board_config_kernel voiceblue_config[] = { 158 { OMAP_TAG_USB, &voiceblue_usb_config }, 159 { OMAP_TAG_MMC, &voiceblue_mmc_config }, 160 { OMAP_TAG_UART, &voiceblue_uart_config }, 161}; 162 163static void __init voiceblue_init_irq(void) 164{ 165 omap1_init_common_hw(); 166 omap_init_irq(); 167 omap_gpio_init(); 168} 169 170static void __init voiceblue_init(void) 171{ 172 /* Watchdog */ 173 omap_request_gpio(0); 174 /* smc91x reset */ 175 omap_request_gpio(7); 176 omap_set_gpio_direction(7, 0); 177 omap_set_gpio_dataout(7, 1); 178 udelay(2); /* wait at least 100ns */ 179 omap_set_gpio_dataout(7, 0); 180 mdelay(50); /* 50ms until PHY ready */ 181 /* smc91x interrupt pin */ 182 omap_request_gpio(8); 183 /* 16C554 reset*/ 184 omap_request_gpio(6); 185 omap_set_gpio_direction(6, 0); 186 omap_set_gpio_dataout(6, 0); 187 /* 16C554 interrupt pins */ 188 omap_request_gpio(12); 189 omap_request_gpio(13); 190 omap_request_gpio(14); 191 omap_request_gpio(15); 192 set_irq_type(OMAP_GPIO_IRQ(12), IRQT_RISING); 193 set_irq_type(OMAP_GPIO_IRQ(13), IRQT_RISING); 194 set_irq_type(OMAP_GPIO_IRQ(14), IRQT_RISING); 195 set_irq_type(OMAP_GPIO_IRQ(15), IRQT_RISING); 196 197 platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices)); 198 omap_board_config = voiceblue_config; 199 omap_board_config_size = ARRAY_SIZE(voiceblue_config); 200 omap_serial_init(); 201 202 /* There is a good chance board is going up, so enable power LED 203 * (it is connected through invertor) */ 204 omap_writeb(0x00, OMAP_LPG1_LCR); 205 omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */ 206} 207 208static void __init voiceblue_map_io(void) 209{ 210 omap1_map_common_io(); 211} 212 213#define MACHINE_PANICED 1 214#define MACHINE_REBOOTING 2 215#define MACHINE_REBOOT 4 216static unsigned long machine_state; 217 218static int panic_event(struct notifier_block *this, unsigned long event, 219 void *ptr) 220{ 221 if (test_and_set_bit(MACHINE_PANICED, &machine_state)) 222 return NOTIFY_DONE; 223 224 /* Flash power LED */ 225 omap_writeb(0x78, OMAP_LPG1_LCR); 226 omap_writeb(0x01, OMAP_LPG1_PMR); /* Enable clock */ 227 228 return NOTIFY_DONE; 229} 230 231static struct notifier_block panic_block = { 232 .notifier_call = panic_event, 233}; 234 235static int __init voiceblue_setup(void) 236{ 237 /* Setup panic notifier */ 238 notifier_chain_register(&panic_notifier_list, &panic_block); 239 240 return 0; 241} 242postcore_initcall(voiceblue_setup); 243 244static int wdt_gpio_state; 245 246void voiceblue_wdt_enable(void) 247{ 248 omap_set_gpio_direction(0, 0); 249 omap_set_gpio_dataout(0, 0); 250 omap_set_gpio_dataout(0, 1); 251 omap_set_gpio_dataout(0, 0); 252 wdt_gpio_state = 0; 253} 254 255void voiceblue_wdt_disable(void) 256{ 257 omap_set_gpio_dataout(0, 0); 258 omap_set_gpio_dataout(0, 1); 259 omap_set_gpio_dataout(0, 0); 260 omap_set_gpio_direction(0, 1); 261} 262 263void voiceblue_wdt_ping(void) 264{ 265 if (test_bit(MACHINE_REBOOT, &machine_state)) 266 return; 267 268 wdt_gpio_state = !wdt_gpio_state; 269 omap_set_gpio_dataout(0, wdt_gpio_state); 270} 271 272void voiceblue_reset(void) 273{ 274 set_bit(MACHINE_REBOOT, &machine_state); 275 voiceblue_wdt_enable(); 276 while (1) ; 277} 278 279EXPORT_SYMBOL(voiceblue_wdt_enable); 280EXPORT_SYMBOL(voiceblue_wdt_disable); 281EXPORT_SYMBOL(voiceblue_wdt_ping); 282 283MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910") 284 /* Maintainer: Ladislav Michl <michl@2n.cz> */ 285 .phys_io = 0xfff00000, 286 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, 287 .boot_params = 0x10000100, 288 .map_io = voiceblue_map_io, 289 .init_irq = voiceblue_init_irq, 290 .init_machine = voiceblue_init, 291 .timer = &omap_timer, 292MACHINE_END 293