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/irq.h> 19#include <linux/init.h> 20#include <linux/kernel.h> 21#include <linux/mtd/physmap.h> 22#include <linux/notifier.h> 23#include <linux/reboot.h> 24#include <linux/serial_8250.h> 25#include <linux/serial_reg.h> 26#include <linux/smc91x.h> 27 28#include <mach/hardware.h> 29#include <asm/mach-types.h> 30#include <asm/mach/arch.h> 31#include <asm/mach/map.h> 32 33#include <plat/common.h> 34#include <mach/gpio.h> 35#include <plat/flash.h> 36#include <plat/mux.h> 37#include <plat/tc.h> 38#include <plat/usb.h> 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 physmap_flash_data voiceblue_flash_data = { 91 .width = 2, 92 .set_vpp = omap1_set_vpp, 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 = "physmap-flash", 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 smc91x_platdata voiceblue_smc91x_info = { 112 .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, 113 .leda = RPC_LED_100_10, 114 .ledb = RPC_LED_TX_RX, 115}; 116 117static struct resource voiceblue_smc91x_resources[] = { 118 [0] = { 119 .start = OMAP_CS2_PHYS + 0x300, 120 .end = OMAP_CS2_PHYS + 0x300 + 16, 121 .flags = IORESOURCE_MEM, 122 }, 123 [1] = { 124 .start = OMAP_GPIO_IRQ(8), 125 .end = OMAP_GPIO_IRQ(8), 126 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 127 }, 128}; 129 130static struct platform_device voiceblue_smc91x_device = { 131 .name = "smc91x", 132 .id = 0, 133 .dev = { 134 .platform_data = &voiceblue_smc91x_info, 135 }, 136 .num_resources = ARRAY_SIZE(voiceblue_smc91x_resources), 137 .resource = voiceblue_smc91x_resources, 138}; 139 140static struct platform_device *voiceblue_devices[] __initdata = { 141 &voiceblue_flash_device, 142 &voiceblue_smc91x_device, 143}; 144 145static struct omap_usb_config voiceblue_usb_config __initdata = { 146 .hmc_mode = 3, 147 .register_host = 1, 148 .register_dev = 1, 149 .pins[0] = 2, 150 .pins[1] = 6, 151 .pins[2] = 6, 152}; 153 154static struct omap_board_config_kernel voiceblue_config[] = { 155}; 156 157static void __init voiceblue_init_irq(void) 158{ 159 omap1_init_common_hw(); 160 omap_init_irq(); 161 omap_gpio_init(); 162} 163 164static void __init voiceblue_init(void) 165{ 166 /* mux pins for uarts */ 167 omap_cfg_reg(UART1_TX); 168 omap_cfg_reg(UART1_RTS); 169 omap_cfg_reg(UART2_TX); 170 omap_cfg_reg(UART2_RTS); 171 omap_cfg_reg(UART3_TX); 172 omap_cfg_reg(UART3_RX); 173 174 /* Watchdog */ 175 gpio_request(0, "Watchdog"); 176 /* smc91x reset */ 177 gpio_request(7, "SMC91x reset"); 178 gpio_direction_output(7, 1); 179 udelay(2); /* wait at least 100ns */ 180 gpio_set_value(7, 0); 181 mdelay(50); /* 50ms until PHY ready */ 182 /* smc91x interrupt pin */ 183 gpio_request(8, "SMC91x irq"); 184 /* 16C554 reset*/ 185 gpio_request(6, "16C554 reset"); 186 gpio_direction_output(6, 0); 187 /* 16C554 interrupt pins */ 188 gpio_request(12, "16C554 irq"); 189 gpio_request(13, "16C554 irq"); 190 gpio_request(14, "16C554 irq"); 191 gpio_request(15, "16C554 irq"); 192 set_irq_type(gpio_to_irq(12), IRQ_TYPE_EDGE_RISING); 193 set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING); 194 set_irq_type(gpio_to_irq(14), IRQ_TYPE_EDGE_RISING); 195 set_irq_type(gpio_to_irq(15), IRQ_TYPE_EDGE_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 omap1_usb_init(&voiceblue_usb_config); 202 omap_register_i2c_bus(1, 100, NULL, 0); 203 204 /* There is a good chance board is going up, so enable power LED 205 * (it is connected through invertor) */ 206 omap_writeb(0x00, OMAP_LPG1_LCR); 207 omap_writeb(0x00, OMAP_LPG1_PMR); /* Disable clock */ 208} 209 210static void __init voiceblue_map_io(void) 211{ 212 omap1_map_common_io(); 213} 214 215#define MACHINE_PANICED 1 216#define MACHINE_REBOOTING 2 217#define MACHINE_REBOOT 4 218static unsigned long machine_state; 219 220static int panic_event(struct notifier_block *this, unsigned long event, 221 void *ptr) 222{ 223 if (test_and_set_bit(MACHINE_PANICED, &machine_state)) 224 return NOTIFY_DONE; 225 226 /* Flash power LED */ 227 omap_writeb(0x78, OMAP_LPG1_LCR); 228 omap_writeb(0x01, OMAP_LPG1_PMR); /* Enable clock */ 229 230 return NOTIFY_DONE; 231} 232 233static struct notifier_block panic_block = { 234 .notifier_call = panic_event, 235}; 236 237static int __init voiceblue_setup(void) 238{ 239 /* Setup panic notifier */ 240 atomic_notifier_chain_register(&panic_notifier_list, &panic_block); 241 242 return 0; 243} 244postcore_initcall(voiceblue_setup); 245 246static int wdt_gpio_state; 247 248void voiceblue_wdt_enable(void) 249{ 250 gpio_direction_output(0, 0); 251 gpio_set_value(0, 1); 252 gpio_set_value(0, 0); 253 wdt_gpio_state = 0; 254} 255 256void voiceblue_wdt_disable(void) 257{ 258 gpio_set_value(0, 0); 259 gpio_set_value(0, 1); 260 gpio_set_value(0, 0); 261 gpio_direction_input(0); 262} 263 264void voiceblue_wdt_ping(void) 265{ 266 if (test_bit(MACHINE_REBOOT, &machine_state)) 267 return; 268 269 wdt_gpio_state = !wdt_gpio_state; 270 gpio_set_value(0, wdt_gpio_state); 271} 272 273void voiceblue_reset(void) 274{ 275 set_bit(MACHINE_REBOOT, &machine_state); 276 voiceblue_wdt_enable(); 277 while (1) ; 278} 279 280EXPORT_SYMBOL(voiceblue_wdt_enable); 281EXPORT_SYMBOL(voiceblue_wdt_disable); 282EXPORT_SYMBOL(voiceblue_wdt_ping); 283 284MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910") 285 /* Maintainer: Ladislav Michl <michl@2n.cz> */ 286 .phys_io = 0xfff00000, 287 .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, 288 .boot_params = 0x10000100, 289 .map_io = voiceblue_map_io, 290 .reserve = omap_reserve, 291 .init_irq = voiceblue_init_irq, 292 .init_machine = voiceblue_init, 293 .timer = &omap_timer, 294MACHINE_END 295