/arch/arm/mach-omap/board-voiceblue.c

https://bitbucket.org/evzijst/gittest · C · 256 lines · 199 code · 34 blank · 23 comment · 3 complexity · 6b5d9020929853efb69687b28bd5ecd3 MD5 · raw file

  1. /*
  2. * linux/arch/arm/mach-omap/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. #include <linux/delay.h>
  15. #include <linux/device.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/init.h>
  18. #include <linux/kernel.h>
  19. #include <linux/notifier.h>
  20. #include <linux/reboot.h>
  21. #include <linux/serial_8250.h>
  22. #include <linux/serial_reg.h>
  23. #include <asm/hardware.h>
  24. #include <asm/mach-types.h>
  25. #include <asm/mach/arch.h>
  26. #include <asm/mach/map.h>
  27. #include <asm/arch/gpio.h>
  28. #include <asm/arch/tc.h>
  29. #include <asm/arch/mux.h>
  30. #include <asm/arch/usb.h>
  31. #include "common.h"
  32. extern void omap_init_time(void);
  33. extern int omap_gpio_init(void);
  34. static struct plat_serial8250_port voiceblue_ports[] = {
  35. {
  36. .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x40000),
  37. .irq = OMAP_GPIO_IRQ(12),
  38. .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
  39. .iotype = UPIO_MEM,
  40. .regshift = 1,
  41. .uartclk = 3686400,
  42. },
  43. {
  44. .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x50000),
  45. .irq = OMAP_GPIO_IRQ(13),
  46. .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
  47. .iotype = UPIO_MEM,
  48. .regshift = 1,
  49. .uartclk = 3686400,
  50. },
  51. {
  52. .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x60000),
  53. .irq = OMAP_GPIO_IRQ(14),
  54. .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
  55. .iotype = UPIO_MEM,
  56. .regshift = 1,
  57. .uartclk = 3686400,
  58. },
  59. {
  60. .mapbase = (unsigned long)(OMAP_CS1_PHYS + 0x70000),
  61. .irq = OMAP_GPIO_IRQ(15),
  62. .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP,
  63. .iotype = UPIO_MEM,
  64. .regshift = 1,
  65. .uartclk = 3686400,
  66. },
  67. { },
  68. };
  69. static struct platform_device serial_device = {
  70. .name = "serial8250",
  71. .id = 1,
  72. .dev = {
  73. .platform_data = voiceblue_ports,
  74. },
  75. };
  76. static int __init ext_uart_init(void)
  77. {
  78. return platform_device_register(&serial_device);
  79. }
  80. arch_initcall(ext_uart_init);
  81. static struct resource voiceblue_smc91x_resources[] = {
  82. [0] = {
  83. .start = OMAP_CS2_PHYS + 0x300,
  84. .end = OMAP_CS2_PHYS + 0x300 + 16,
  85. .flags = IORESOURCE_MEM,
  86. },
  87. [1] = {
  88. .start = OMAP_GPIO_IRQ(8),
  89. .end = OMAP_GPIO_IRQ(8),
  90. .flags = IORESOURCE_IRQ,
  91. },
  92. };
  93. static struct platform_device voiceblue_smc91x_device = {
  94. .name = "smc91x",
  95. .id = 0,
  96. .num_resources = ARRAY_SIZE(voiceblue_smc91x_resources),
  97. .resource = voiceblue_smc91x_resources,
  98. };
  99. static struct platform_device *voiceblue_devices[] __initdata = {
  100. &voiceblue_smc91x_device,
  101. };
  102. static struct omap_usb_config voiceblue_usb_config __initdata = {
  103. .hmc_mode = 3,
  104. .register_host = 1,
  105. .register_dev = 1,
  106. .pins[0] = 2,
  107. .pins[1] = 6,
  108. .pins[2] = 6,
  109. };
  110. static struct omap_board_config_kernel voiceblue_config[] = {
  111. { OMAP_TAG_USB, &voiceblue_usb_config },
  112. };
  113. static void __init voiceblue_init_irq(void)
  114. {
  115. omap_init_irq();
  116. omap_gpio_init();
  117. }
  118. static void __init voiceblue_init(void)
  119. {
  120. /* There is a good chance board is going up, so enable Power LED
  121. * (it is connected through invertor) */
  122. omap_writeb(0x00, OMAP_LPG1_LCR);
  123. /* Watchdog */
  124. omap_request_gpio(0);
  125. /* smc91x reset */
  126. omap_request_gpio(7);
  127. omap_set_gpio_direction(7, 0);
  128. omap_set_gpio_dataout(7, 1);
  129. udelay(2); /* wait at least 100ns */
  130. omap_set_gpio_dataout(7, 0);
  131. mdelay(50); /* 50ms until PHY ready */
  132. /* smc91x interrupt pin */
  133. omap_request_gpio(8);
  134. omap_set_gpio_edge_ctrl(8, OMAP_GPIO_RISING_EDGE);
  135. /* 16C554 reset*/
  136. omap_request_gpio(6);
  137. omap_set_gpio_direction(6, 0);
  138. omap_set_gpio_dataout(6, 0);
  139. /* 16C554 interrupt pins */
  140. omap_request_gpio(12);
  141. omap_request_gpio(13);
  142. omap_request_gpio(14);
  143. omap_request_gpio(15);
  144. omap_set_gpio_edge_ctrl(12, OMAP_GPIO_RISING_EDGE);
  145. omap_set_gpio_edge_ctrl(13, OMAP_GPIO_RISING_EDGE);
  146. omap_set_gpio_edge_ctrl(14, OMAP_GPIO_RISING_EDGE);
  147. omap_set_gpio_edge_ctrl(15, OMAP_GPIO_RISING_EDGE);
  148. platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
  149. omap_board_config = voiceblue_config;
  150. omap_board_config_size = ARRAY_SIZE(voiceblue_config);
  151. }
  152. static int __initdata omap_serial_ports[OMAP_MAX_NR_PORTS] = {1, 1, 1};
  153. static void __init voiceblue_map_io(void)
  154. {
  155. omap_map_io();
  156. omap_serial_init(omap_serial_ports);
  157. }
  158. #define MACHINE_PANICED 1
  159. #define MACHINE_REBOOTING 2
  160. #define MACHINE_REBOOT 4
  161. static unsigned long machine_state;
  162. static int panic_event(struct notifier_block *this, unsigned long event,
  163. void *ptr)
  164. {
  165. if (test_and_set_bit(MACHINE_PANICED, &machine_state))
  166. return NOTIFY_DONE;
  167. /* Flash Power LED
  168. * (TODO: Enable clock right way (enabled in bootloader already)) */
  169. omap_writeb(0x78, OMAP_LPG1_LCR);
  170. return NOTIFY_DONE;
  171. }
  172. static struct notifier_block panic_block = {
  173. .notifier_call = panic_event,
  174. };
  175. static int __init setup_notifier(void)
  176. {
  177. /* Setup panic notifier */
  178. notifier_chain_register(&panic_notifier_list, &panic_block);
  179. return 0;
  180. }
  181. postcore_initcall(setup_notifier);
  182. static int wdt_gpio_state;
  183. void voiceblue_wdt_enable(void)
  184. {
  185. omap_set_gpio_direction(0, 0);
  186. omap_set_gpio_dataout(0, 0);
  187. omap_set_gpio_dataout(0, 1);
  188. omap_set_gpio_dataout(0, 0);
  189. wdt_gpio_state = 0;
  190. }
  191. void voiceblue_wdt_disable(void)
  192. {
  193. omap_set_gpio_dataout(0, 0);
  194. omap_set_gpio_dataout(0, 1);
  195. omap_set_gpio_dataout(0, 0);
  196. omap_set_gpio_direction(0, 1);
  197. }
  198. void voiceblue_wdt_ping(void)
  199. {
  200. if (test_bit(MACHINE_REBOOT, &machine_state))
  201. return;
  202. wdt_gpio_state = !wdt_gpio_state;
  203. omap_set_gpio_dataout(0, wdt_gpio_state);
  204. }
  205. void voiceblue_reset(void)
  206. {
  207. set_bit(MACHINE_REBOOT, &machine_state);
  208. voiceblue_wdt_enable();
  209. while (1) ;
  210. }
  211. EXPORT_SYMBOL(voiceblue_wdt_enable);
  212. EXPORT_SYMBOL(voiceblue_wdt_disable);
  213. EXPORT_SYMBOL(voiceblue_wdt_ping);
  214. MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910")
  215. MAINTAINER("Ladislav Michl <michl@2n.cz>")
  216. BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000)
  217. BOOT_PARAMS(0x10000100)
  218. MAPIO(voiceblue_map_io)
  219. INITIRQ(voiceblue_init_irq)
  220. INIT_MACHINE(voiceblue_init)
  221. .timer = &omap_timer,
  222. MACHINE_END