net2big-setup.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. /*
  2. * arch/arm/mach-orion5x/net2big-setup.c
  3. *
  4. * LaCie 2Big Network NAS setup
  5. *
  6. * Copyright (C) 2009 Simon Guinot <sguinot@lacie.com>
  7. *
  8. * This file is licensed under the terms of the GNU General Public
  9. * License version 2. This program is licensed "as is" without any
  10. * warranty of any kind, whether express or implied.
  11. */
  12. #include <linux/kernel.h>
  13. #include <linux/init.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/mtd/physmap.h>
  16. #include <linux/mv643xx_eth.h>
  17. #include <linux/leds.h>
  18. #include <linux/gpio_keys.h>
  19. #include <linux/input.h>
  20. #include <linux/i2c.h>
  21. #include <linux/ata_platform.h>
  22. #include <linux/gpio.h>
  23. #include <linux/delay.h>
  24. #include <asm/mach-types.h>
  25. #include <asm/mach/arch.h>
  26. #include <mach/orion5x.h>
  27. #include "common.h"
  28. #include "mpp.h"
  29. /*****************************************************************************
  30. * LaCie 2Big Network Info
  31. ****************************************************************************/
  32. /*
  33. * 512KB NOR flash Device bus boot chip select
  34. */
  35. #define NET2BIG_NOR_BOOT_BASE 0xfff80000
  36. #define NET2BIG_NOR_BOOT_SIZE SZ_512K
  37. /*****************************************************************************
  38. * 512KB NOR Flash on Boot Device
  39. ****************************************************************************/
  40. /*
  41. * TODO: Check write support on flash MX29LV400CBTC-70G
  42. */
  43. static struct mtd_partition net2big_partitions[] = {
  44. {
  45. .name = "Full512kb",
  46. .size = MTDPART_SIZ_FULL,
  47. .offset = 0x00000000,
  48. .mask_flags = MTD_WRITEABLE,
  49. },
  50. };
  51. static struct physmap_flash_data net2big_nor_flash_data = {
  52. .width = 1,
  53. .parts = net2big_partitions,
  54. .nr_parts = ARRAY_SIZE(net2big_partitions),
  55. };
  56. static struct resource net2big_nor_flash_resource = {
  57. .flags = IORESOURCE_MEM,
  58. .start = NET2BIG_NOR_BOOT_BASE,
  59. .end = NET2BIG_NOR_BOOT_BASE
  60. + NET2BIG_NOR_BOOT_SIZE - 1,
  61. };
  62. static struct platform_device net2big_nor_flash = {
  63. .name = "physmap-flash",
  64. .id = 0,
  65. .dev = {
  66. .platform_data = &net2big_nor_flash_data,
  67. },
  68. .num_resources = 1,
  69. .resource = &net2big_nor_flash_resource,
  70. };
  71. /*****************************************************************************
  72. * Ethernet
  73. ****************************************************************************/
  74. static struct mv643xx_eth_platform_data net2big_eth_data = {
  75. .phy_addr = MV643XX_ETH_PHY_ADDR(8),
  76. };
  77. /*****************************************************************************
  78. * I2C devices
  79. ****************************************************************************/
  80. /*
  81. * i2c addr | chip | description
  82. * 0x32 | Ricoh 5C372b | RTC
  83. * 0x50 | HT24LC08 | eeprom (1kB)
  84. */
  85. static struct i2c_board_info __initdata net2big_i2c_devices[] = {
  86. {
  87. I2C_BOARD_INFO("rs5c372b", 0x32),
  88. }, {
  89. I2C_BOARD_INFO("24c08", 0x50),
  90. },
  91. };
  92. /*****************************************************************************
  93. * SATA
  94. ****************************************************************************/
  95. static struct mv_sata_platform_data net2big_sata_data = {
  96. .n_ports = 2,
  97. };
  98. #define NET2BIG_GPIO_SATA_POWER_REQ 19
  99. #define NET2BIG_GPIO_SATA0_POWER 23
  100. #define NET2BIG_GPIO_SATA1_POWER 25
  101. static void __init net2big_sata_power_init(void)
  102. {
  103. int err;
  104. /* Configure GPIOs over MPP max number. */
  105. orion_gpio_set_valid(NET2BIG_GPIO_SATA0_POWER, 1);
  106. orion_gpio_set_valid(NET2BIG_GPIO_SATA1_POWER, 1);
  107. err = gpio_request(NET2BIG_GPIO_SATA0_POWER, "SATA0 power status");
  108. if (err == 0) {
  109. err = gpio_direction_input(NET2BIG_GPIO_SATA0_POWER);
  110. if (err)
  111. gpio_free(NET2BIG_GPIO_SATA0_POWER);
  112. }
  113. if (err) {
  114. pr_err("net2big: failed to setup SATA0 power GPIO\n");
  115. return;
  116. }
  117. err = gpio_request(NET2BIG_GPIO_SATA1_POWER, "SATA1 power status");
  118. if (err == 0) {
  119. err = gpio_direction_input(NET2BIG_GPIO_SATA1_POWER);
  120. if (err)
  121. gpio_free(NET2BIG_GPIO_SATA1_POWER);
  122. }
  123. if (err) {
  124. pr_err("net2big: failed to setup SATA1 power GPIO\n");
  125. goto err_free_1;
  126. }
  127. err = gpio_request(NET2BIG_GPIO_SATA_POWER_REQ, "SATA power request");
  128. if (err == 0) {
  129. err = gpio_direction_output(NET2BIG_GPIO_SATA_POWER_REQ, 0);
  130. if (err)
  131. gpio_free(NET2BIG_GPIO_SATA_POWER_REQ);
  132. }
  133. if (err) {
  134. pr_err("net2big: failed to setup SATA power request GPIO\n");
  135. goto err_free_2;
  136. }
  137. if (gpio_get_value(NET2BIG_GPIO_SATA0_POWER) &&
  138. gpio_get_value(NET2BIG_GPIO_SATA1_POWER)) {
  139. return;
  140. }
  141. /*
  142. * SATA power up on both disk is done by pulling high the CPLD power
  143. * request line. The 300ms delay is related to the CPLD clock and is
  144. * needed to be sure that the CPLD has take into account the low line
  145. * status.
  146. */
  147. msleep(300);
  148. gpio_set_value(NET2BIG_GPIO_SATA_POWER_REQ, 1);
  149. pr_info("net2big: power up SATA hard disks\n");
  150. return;
  151. err_free_2:
  152. gpio_free(NET2BIG_GPIO_SATA1_POWER);
  153. err_free_1:
  154. gpio_free(NET2BIG_GPIO_SATA0_POWER);
  155. return;
  156. }
  157. /*****************************************************************************
  158. * GPIO LEDs
  159. ****************************************************************************/
  160. /*
  161. * The power front LEDs (blue and red) and SATA red LEDs are controlled via a
  162. * single GPIO line and are compatible with the leds-gpio driver.
  163. *
  164. * The SATA blue LEDs have some hardware blink capabilities which are detailled
  165. * in the following array:
  166. *
  167. * SATAx blue LED | SATAx activity | LED state
  168. * | |
  169. * 0 | 0 | blink (rate 300ms)
  170. * 1 | 0 | off
  171. * ? | 1 | on
  172. *
  173. * Notes: The blue and the red front LED's can't be on at the same time.
  174. * Blue LED have priority.
  175. */
  176. #define NET2BIG_GPIO_PWR_RED_LED 6
  177. #define NET2BIG_GPIO_PWR_BLUE_LED 16
  178. #define NET2BIG_GPIO_PWR_LED_BLINK_STOP 7
  179. #define NET2BIG_GPIO_SATA0_RED_LED 11
  180. #define NET2BIG_GPIO_SATA1_RED_LED 10
  181. #define NET2BIG_GPIO_SATA0_BLUE_LED 17
  182. #define NET2BIG_GPIO_SATA1_BLUE_LED 13
  183. static struct gpio_led net2big_leds[] = {
  184. {
  185. .name = "net2big:red:power",
  186. .gpio = NET2BIG_GPIO_PWR_RED_LED,
  187. },
  188. {
  189. .name = "net2big:blue:power",
  190. .gpio = NET2BIG_GPIO_PWR_BLUE_LED,
  191. },
  192. {
  193. .name = "net2big:red:sata0",
  194. .gpio = NET2BIG_GPIO_SATA0_RED_LED,
  195. },
  196. {
  197. .name = "net2big:red:sata1",
  198. .gpio = NET2BIG_GPIO_SATA1_RED_LED,
  199. },
  200. };
  201. static struct gpio_led_platform_data net2big_led_data = {
  202. .num_leds = ARRAY_SIZE(net2big_leds),
  203. .leds = net2big_leds,
  204. };
  205. static struct platform_device net2big_gpio_leds = {
  206. .name = "leds-gpio",
  207. .id = -1,
  208. .dev = {
  209. .platform_data = &net2big_led_data,
  210. },
  211. };
  212. static void __init net2big_gpio_leds_init(void)
  213. {
  214. int err;
  215. /* Stop initial CPLD slow red/blue blinking on power LED. */
  216. err = gpio_request(NET2BIG_GPIO_PWR_LED_BLINK_STOP,
  217. "Power LED blink stop");
  218. if (err == 0) {
  219. err = gpio_direction_output(NET2BIG_GPIO_PWR_LED_BLINK_STOP, 1);
  220. if (err)
  221. gpio_free(NET2BIG_GPIO_PWR_LED_BLINK_STOP);
  222. }
  223. if (err)
  224. pr_err("net2big: failed to setup power LED blink GPIO\n");
  225. /*
  226. * Configure SATA0 and SATA1 blue LEDs to blink in relation with the
  227. * hard disk activity.
  228. */
  229. err = gpio_request(NET2BIG_GPIO_SATA0_BLUE_LED,
  230. "SATA0 blue LED control");
  231. if (err == 0) {
  232. err = gpio_direction_output(NET2BIG_GPIO_SATA0_BLUE_LED, 1);
  233. if (err)
  234. gpio_free(NET2BIG_GPIO_SATA0_BLUE_LED);
  235. }
  236. if (err)
  237. pr_err("net2big: failed to setup SATA0 blue LED GPIO\n");
  238. err = gpio_request(NET2BIG_GPIO_SATA1_BLUE_LED,
  239. "SATA1 blue LED control");
  240. if (err == 0) {
  241. err = gpio_direction_output(NET2BIG_GPIO_SATA1_BLUE_LED, 1);
  242. if (err)
  243. gpio_free(NET2BIG_GPIO_SATA1_BLUE_LED);
  244. }
  245. if (err)
  246. pr_err("net2big: failed to setup SATA1 blue LED GPIO\n");
  247. platform_device_register(&net2big_gpio_leds);
  248. }
  249. /****************************************************************************
  250. * GPIO keys
  251. ****************************************************************************/
  252. #define NET2BIG_GPIO_PUSH_BUTTON 18
  253. #define NET2BIG_GPIO_POWER_SWITCH_ON 8
  254. #define NET2BIG_GPIO_POWER_SWITCH_OFF 9
  255. #define NET2BIG_SWITCH_POWER_ON 0x1
  256. #define NET2BIG_SWITCH_POWER_OFF 0x2
  257. static struct gpio_keys_button net2big_buttons[] = {
  258. {
  259. .type = EV_SW,
  260. .code = NET2BIG_SWITCH_POWER_OFF,
  261. .gpio = NET2BIG_GPIO_POWER_SWITCH_OFF,
  262. .desc = "Power rocker switch (auto|off)",
  263. .active_low = 0,
  264. },
  265. {
  266. .type = EV_SW,
  267. .code = NET2BIG_SWITCH_POWER_ON,
  268. .gpio = NET2BIG_GPIO_POWER_SWITCH_ON,
  269. .desc = "Power rocker switch (on|auto)",
  270. .active_low = 0,
  271. },
  272. {
  273. .type = EV_KEY,
  274. .code = KEY_POWER,
  275. .gpio = NET2BIG_GPIO_PUSH_BUTTON,
  276. .desc = "Front Push Button",
  277. .active_low = 0,
  278. },
  279. };
  280. static struct gpio_keys_platform_data net2big_button_data = {
  281. .buttons = net2big_buttons,
  282. .nbuttons = ARRAY_SIZE(net2big_buttons),
  283. };
  284. static struct platform_device net2big_gpio_buttons = {
  285. .name = "gpio-keys",
  286. .id = -1,
  287. .dev = {
  288. .platform_data = &net2big_button_data,
  289. },
  290. };
  291. /*****************************************************************************
  292. * General Setup
  293. ****************************************************************************/
  294. static struct orion5x_mpp_mode net2big_mpp_modes[] __initdata = {
  295. { 0, MPP_GPIO }, /* Raid mode (bit 0) */
  296. { 1, MPP_GPIO }, /* USB port 2 fuse (0 = Fail, 1 = Ok) */
  297. { 2, MPP_GPIO }, /* Raid mode (bit 1) */
  298. { 3, MPP_GPIO }, /* Board ID (bit 0) */
  299. { 4, MPP_GPIO }, /* Fan activity (0 = Off, 1 = On) */
  300. { 5, MPP_GPIO }, /* Fan fail detection */
  301. { 6, MPP_GPIO }, /* Red front LED (0 = Off, 1 = On) */
  302. { 7, MPP_GPIO }, /* Disable initial blinking on front LED */
  303. { 8, MPP_GPIO }, /* Rear power switch (on|auto) */
  304. { 9, MPP_GPIO }, /* Rear power switch (auto|off) */
  305. { 10, MPP_GPIO }, /* SATA 1 red LED (0 = Off, 1 = On) */
  306. { 11, MPP_GPIO }, /* SATA 0 red LED (0 = Off, 1 = On) */
  307. { 12, MPP_GPIO }, /* Board ID (bit 1) */
  308. { 13, MPP_GPIO }, /* SATA 1 blue LED blink control */
  309. { 14, MPP_SATA_LED },
  310. { 15, MPP_SATA_LED },
  311. { 16, MPP_GPIO }, /* Blue front LED control */
  312. { 17, MPP_GPIO }, /* SATA 0 blue LED blink control */
  313. { 18, MPP_GPIO }, /* Front button (0 = Released, 1 = Pushed ) */
  314. { 19, MPP_GPIO }, /* SATA{0,1} power On/Off request */
  315. { -1 }
  316. /* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */
  317. /* 23: SATA 0 power status */
  318. /* 24: Board power off */
  319. /* 25: SATA 1 power status */
  320. };
  321. #define NET2BIG_GPIO_POWER_OFF 24
  322. static void net2big_power_off(void)
  323. {
  324. gpio_set_value(NET2BIG_GPIO_POWER_OFF, 1);
  325. }
  326. static void __init net2big_init(void)
  327. {
  328. /*
  329. * Setup basic Orion functions. Need to be called early.
  330. */
  331. orion5x_init();
  332. orion5x_mpp_conf(net2big_mpp_modes);
  333. /*
  334. * Configure peripherals.
  335. */
  336. orion5x_ehci0_init();
  337. orion5x_ehci1_init();
  338. orion5x_eth_init(&net2big_eth_data);
  339. orion5x_i2c_init();
  340. orion5x_uart0_init();
  341. orion5x_xor_init();
  342. net2big_sata_power_init();
  343. orion5x_sata_init(&net2big_sata_data);
  344. orion5x_setup_dev_boot_win(NET2BIG_NOR_BOOT_BASE,
  345. NET2BIG_NOR_BOOT_SIZE);
  346. platform_device_register(&net2big_nor_flash);
  347. platform_device_register(&net2big_gpio_buttons);
  348. net2big_gpio_leds_init();
  349. i2c_register_board_info(0, net2big_i2c_devices,
  350. ARRAY_SIZE(net2big_i2c_devices));
  351. orion_gpio_set_valid(NET2BIG_GPIO_POWER_OFF, 1);
  352. if (gpio_request(NET2BIG_GPIO_POWER_OFF, "power-off") == 0 &&
  353. gpio_direction_output(NET2BIG_GPIO_POWER_OFF, 0) == 0)
  354. pm_power_off = net2big_power_off;
  355. else
  356. pr_err("net2big: failed to configure power-off GPIO\n");
  357. pr_notice("net2big: Flash writing is not yet supported.\n");
  358. }
  359. /* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
  360. MACHINE_START(NET2BIG, "LaCie 2Big Network")
  361. .phys_io = ORION5X_REGS_PHYS_BASE,
  362. .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
  363. .boot_params = 0x00000100,
  364. .init_machine = net2big_init,
  365. .map_io = orion5x_map_io,
  366. .init_irq = orion5x_init_irq,
  367. .timer = &orion5x_timer,
  368. .fixup = tag_fixup_mem32,
  369. MACHINE_END