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