Merge git://git.kernel.org/pub/scm/linux/kernel/git/nico/orion
[~shefty/rdma-dev.git] / arch / arm / mach-kirkwood / netxbig_v2-setup.c
1 /*
2  * arch/arm/mach-kirkwood/netxbig_v2-setup.c
3  *
4  * LaCie 2Big and 5Big Network v2 board setup
5  *
6  * Copyright (C) 2010 Simon Guinot <sguinot@lacie.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <linux/kernel.h>
24 #include <linux/init.h>
25 #include <linux/platform_device.h>
26 #include <linux/ata_platform.h>
27 #include <linux/mv643xx_eth.h>
28 #include <linux/input.h>
29 #include <linux/gpio.h>
30 #include <linux/gpio_keys.h>
31 #include <linux/leds.h>
32 #include <asm/mach-types.h>
33 #include <asm/mach/arch.h>
34 #include <mach/kirkwood.h>
35 #include <mach/leds-netxbig.h>
36 #include "common.h"
37 #include "mpp.h"
38 #include "lacie_v2-common.h"
39
40 /*****************************************************************************
41  * Ethernet
42  ****************************************************************************/
43
44 static struct mv643xx_eth_platform_data netxbig_v2_ge00_data = {
45         .phy_addr       = MV643XX_ETH_PHY_ADDR(8),
46 };
47
48 static struct mv643xx_eth_platform_data netxbig_v2_ge01_data = {
49         .phy_addr       = MV643XX_ETH_PHY_ADDR(0),
50 };
51
52 /*****************************************************************************
53  * SATA
54  ****************************************************************************/
55
56 static struct mv_sata_platform_data netxbig_v2_sata_data = {
57         .n_ports        = 2,
58 };
59
60 /*****************************************************************************
61  * GPIO keys
62  ****************************************************************************/
63
64 #define NETXBIG_V2_GPIO_SWITCH_POWER_ON         13
65 #define NETXBIG_V2_GPIO_SWITCH_POWER_OFF        15
66 #define NETXBIG_V2_GPIO_FUNC_BUTTON             34
67
68 #define NETXBIG_V2_SWITCH_POWER_ON              0x1
69 #define NETXBIG_V2_SWITCH_POWER_OFF             0x2
70
71 static struct gpio_keys_button netxbig_v2_buttons[] = {
72         [0] = {
73                 .type           = EV_SW,
74                 .code           = NETXBIG_V2_SWITCH_POWER_ON,
75                 .gpio           = NETXBIG_V2_GPIO_SWITCH_POWER_ON,
76                 .desc           = "Back power switch (on|auto)",
77                 .active_low     = 1,
78         },
79         [1] = {
80                 .type           = EV_SW,
81                 .code           = NETXBIG_V2_SWITCH_POWER_OFF,
82                 .gpio           = NETXBIG_V2_GPIO_SWITCH_POWER_OFF,
83                 .desc           = "Back power switch (auto|off)",
84                 .active_low     = 1,
85         },
86         [2] = {
87                 .code           = KEY_OPTION,
88                 .gpio           = NETXBIG_V2_GPIO_FUNC_BUTTON,
89                 .desc           = "Function button",
90                 .active_low     = 1,
91         },
92 };
93
94 static struct gpio_keys_platform_data netxbig_v2_button_data = {
95         .buttons        = netxbig_v2_buttons,
96         .nbuttons       = ARRAY_SIZE(netxbig_v2_buttons),
97 };
98
99 static struct platform_device netxbig_v2_gpio_buttons = {
100         .name           = "gpio-keys",
101         .id             = -1,
102         .dev            = {
103                 .platform_data  = &netxbig_v2_button_data,
104         },
105 };
106
107 /*****************************************************************************
108  * GPIO extension LEDs
109  ****************************************************************************/
110
111 /*
112  * The LEDs are controlled by a CPLD and can be configured through a GPIO
113  * extension bus:
114  *
115  * - address register : bit [0-2] -> GPIO [47-49]
116  * - data register    : bit [0-2] -> GPIO [44-46]
117  * - enable register  : GPIO 29
118  */
119
120 static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 };
121 static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 };
122
123 static struct netxbig_gpio_ext netxbig_v2_gpio_ext = {
124         .addr           = netxbig_v2_gpio_ext_addr,
125         .num_addr       = ARRAY_SIZE(netxbig_v2_gpio_ext_addr),
126         .data           = netxbig_v2_gpio_ext_data,
127         .num_data       = ARRAY_SIZE(netxbig_v2_gpio_ext_data),
128         .enable         = 29,
129 };
130
131 /*
132  * Address register selection:
133  *
134  * addr | register
135  * ----------------------------
136  *   0  | front LED
137  *   1  | front LED brightness
138  *   2  | SATA LED brightness
139  *   3  | SATA0 LED
140  *   4  | SATA1 LED
141  *   5  | SATA2 LED
142  *   6  | SATA3 LED
143  *   7  | SATA4 LED
144  *
145  * Data register configuration:
146  *
147  * data | LED brightness
148  * -------------------------------------------------
149  *   0  | min (off)
150  *   -  | -
151  *   7  | max
152  *
153  * data | front LED mode
154  * -------------------------------------------------
155  *   0  | fix off
156  *   1  | fix blue on
157  *   2  | fix red on
158  *   3  | blink blue on=1 sec and blue off=1 sec
159  *   4  | blink red on=1 sec and red off=1 sec
160  *   5  | blink blue on=2.5 sec and red on=0.5 sec
161  *   6  | blink blue on=1 sec and red on=1 sec
162  *   7  | blink blue on=0.5 sec and blue off=2.5 sec
163  *
164  * data | SATA LED mode
165  * -------------------------------------------------
166  *   0  | fix off
167  *   1  | SATA activity blink
168  *   2  | fix red on
169  *   3  | blink blue on=1 sec and blue off=1 sec
170  *   4  | blink red on=1 sec and red off=1 sec
171  *   5  | blink blue on=2.5 sec and red on=0.5 sec
172  *   6  | blink blue on=1 sec and red on=1 sec
173  *   7  | fix blue on
174  */
175
176 static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = {
177         [NETXBIG_LED_OFF]       = 0,
178         [NETXBIG_LED_ON]        = 2,
179         [NETXBIG_LED_SATA]      = NETXBIG_LED_INVALID_MODE,
180         [NETXBIG_LED_TIMER1]    = 4,
181         [NETXBIG_LED_TIMER2]    = NETXBIG_LED_INVALID_MODE,
182 };
183
184 static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = {
185         [NETXBIG_LED_OFF]       = 0,
186         [NETXBIG_LED_ON]        = 1,
187         [NETXBIG_LED_SATA]      = NETXBIG_LED_INVALID_MODE,
188         [NETXBIG_LED_TIMER1]    = 3,
189         [NETXBIG_LED_TIMER2]    = 7,
190 };
191
192 static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = {
193         [NETXBIG_LED_OFF]       = 0,
194         [NETXBIG_LED_ON]        = 7,
195         [NETXBIG_LED_SATA]      = 1,
196         [NETXBIG_LED_TIMER1]    = 3,
197         [NETXBIG_LED_TIMER2]    = NETXBIG_LED_INVALID_MODE,
198 };
199
200 static struct netxbig_led_timer netxbig_v2_led_timer[] = {
201         [0] = {
202                 .delay_on       = 500,
203                 .delay_off      = 500,
204                 .mode           = NETXBIG_LED_TIMER1,
205         },
206         [1] = {
207                 .delay_on       = 500,
208                 .delay_off      = 1000,
209                 .mode           = NETXBIG_LED_TIMER2,
210         },
211 };
212
213 #define NETXBIG_LED(_name, maddr, mval, baddr)                  \
214         { .name         = _name,                                \
215           .mode_addr    = maddr,                                \
216           .mode_val     = mval,                                 \
217           .bright_addr  = baddr }
218
219 static struct netxbig_led net2big_v2_leds_ctrl[] = {
220         NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled,  1),
221         NETXBIG_LED("net2big-v2:red:power",  0, netxbig_v2_red_mled,       1),
222         NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
223         NETXBIG_LED("net2big-v2:red:sata0",  3, netxbig_v2_red_mled,       2),
224         NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
225         NETXBIG_LED("net2big-v2:red:sata1",  4, netxbig_v2_red_mled,       2),
226 };
227
228 static struct netxbig_led_platform_data net2big_v2_leds_data = {
229         .gpio_ext       = &netxbig_v2_gpio_ext,
230         .timer          = netxbig_v2_led_timer,
231         .num_timer      = ARRAY_SIZE(netxbig_v2_led_timer),
232         .leds           = net2big_v2_leds_ctrl,
233         .num_leds       = ARRAY_SIZE(net2big_v2_leds_ctrl),
234 };
235
236 static struct netxbig_led net5big_v2_leds_ctrl[] = {
237         NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled,  1),
238         NETXBIG_LED("net5big-v2:red:power",  0, netxbig_v2_red_mled,       1),
239         NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2),
240         NETXBIG_LED("net5big-v2:red:sata0",  3, netxbig_v2_red_mled,       2),
241         NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2),
242         NETXBIG_LED("net5big-v2:red:sata1",  4, netxbig_v2_red_mled,       2),
243         NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2),
244         NETXBIG_LED("net5big-v2:red:sata2",  5, netxbig_v2_red_mled,       2),
245         NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2),
246         NETXBIG_LED("net5big-v2:red:sata3",  6, netxbig_v2_red_mled,       2),
247         NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2),
248         NETXBIG_LED("net5big-v2:red:sata5",  7, netxbig_v2_red_mled,       2),
249 };
250
251 static struct netxbig_led_platform_data net5big_v2_leds_data = {
252         .gpio_ext       = &netxbig_v2_gpio_ext,
253         .timer          = netxbig_v2_led_timer,
254         .num_timer      = ARRAY_SIZE(netxbig_v2_led_timer),
255         .leds           = net5big_v2_leds_ctrl,
256         .num_leds       = ARRAY_SIZE(net5big_v2_leds_ctrl),
257 };
258
259 static struct platform_device netxbig_v2_leds = {
260         .name           = "leds-netxbig",
261         .id             = -1,
262         .dev            = {
263                 .platform_data  = &net2big_v2_leds_data,
264         },
265 };
266
267 /*****************************************************************************
268  * General Setup
269  ****************************************************************************/
270
271 static unsigned int net2big_v2_mpp_config[] __initdata = {
272         MPP0_SPI_SCn,
273         MPP1_SPI_MOSI,
274         MPP2_SPI_SCK,
275         MPP3_SPI_MISO,
276         MPP6_SYSRST_OUTn,
277         MPP7_GPO,               /* Request power-off */
278         MPP8_TW0_SDA,
279         MPP9_TW0_SCK,
280         MPP10_UART0_TXD,
281         MPP11_UART0_RXD,
282         MPP13_GPIO,             /* Rear power switch (on|auto) */
283         MPP14_GPIO,             /* USB fuse alarm */
284         MPP15_GPIO,             /* Rear power switch (auto|off) */
285         MPP16_GPIO,             /* SATA HDD1 power */
286         MPP17_GPIO,             /* SATA HDD2 power */
287         MPP20_SATA1_ACTn,
288         MPP21_SATA0_ACTn,
289         MPP24_GPIO,             /* USB mode select */
290         MPP26_GPIO,             /* USB device vbus */
291         MPP28_GPIO,             /* USB enable host vbus */
292         MPP29_GPIO,             /* GPIO extension ALE */
293         MPP34_GPIO,             /* Rear Push button */
294         MPP35_GPIO,             /* Inhibit switch power-off */
295         MPP36_GPIO,             /* SATA HDD1 presence */
296         MPP37_GPIO,             /* SATA HDD2 presence */
297         MPP40_GPIO,             /* eSATA presence */
298         MPP44_GPIO,             /* GPIO extension (data 0) */
299         MPP45_GPIO,             /* GPIO extension (data 1) */
300         MPP46_GPIO,             /* GPIO extension (data 2) */
301         MPP47_GPIO,             /* GPIO extension (addr 0) */
302         MPP48_GPIO,             /* GPIO extension (addr 1) */
303         MPP49_GPIO,             /* GPIO extension (addr 2) */
304         0
305 };
306
307 static unsigned int net5big_v2_mpp_config[] __initdata = {
308         MPP0_SPI_SCn,
309         MPP1_SPI_MOSI,
310         MPP2_SPI_SCK,
311         MPP3_SPI_MISO,
312         MPP6_SYSRST_OUTn,
313         MPP7_GPO,               /* Request power-off */
314         MPP8_TW0_SDA,
315         MPP9_TW0_SCK,
316         MPP10_UART0_TXD,
317         MPP11_UART0_RXD,
318         MPP13_GPIO,             /* Rear power switch (on|auto) */
319         MPP14_GPIO,             /* USB fuse alarm */
320         MPP15_GPIO,             /* Rear power switch (auto|off) */
321         MPP16_GPIO,             /* SATA HDD1 power */
322         MPP17_GPIO,             /* SATA HDD2 power */
323         MPP20_GE1_TXD0,
324         MPP21_GE1_TXD1,
325         MPP22_GE1_TXD2,
326         MPP23_GE1_TXD3,
327         MPP24_GE1_RXD0,
328         MPP25_GE1_RXD1,
329         MPP26_GE1_RXD2,
330         MPP27_GE1_RXD3,
331         MPP28_GPIO,             /* USB enable host vbus */
332         MPP29_GPIO,             /* GPIO extension ALE */
333         MPP30_GE1_RXCTL,
334         MPP31_GE1_RXCLK,
335         MPP32_GE1_TCLKOUT,
336         MPP33_GE1_TXCTL,
337         MPP34_GPIO,             /* Rear Push button */
338         MPP35_GPIO,             /* Inhibit switch power-off */
339         MPP36_GPIO,             /* SATA HDD1 presence */
340         MPP37_GPIO,             /* SATA HDD2 presence */
341         MPP38_GPIO,             /* SATA HDD3 presence */
342         MPP39_GPIO,             /* SATA HDD4 presence */
343         MPP40_GPIO,             /* SATA HDD5 presence */
344         MPP41_GPIO,             /* SATA HDD3 power */
345         MPP42_GPIO,             /* SATA HDD4 power */
346         MPP43_GPIO,             /* SATA HDD5 power */
347         MPP44_GPIO,             /* GPIO extension (data 0) */
348         MPP45_GPIO,             /* GPIO extension (data 1) */
349         MPP46_GPIO,             /* GPIO extension (data 2) */
350         MPP47_GPIO,             /* GPIO extension (addr 0) */
351         MPP48_GPIO,             /* GPIO extension (addr 1) */
352         MPP49_GPIO,             /* GPIO extension (addr 2) */
353         0
354 };
355
356 #define NETXBIG_V2_GPIO_POWER_OFF               7
357
358 static void netxbig_v2_power_off(void)
359 {
360         gpio_set_value(NETXBIG_V2_GPIO_POWER_OFF, 1);
361 }
362
363 static void __init netxbig_v2_init(void)
364 {
365         /*
366          * Basic setup. Needs to be called early.
367          */
368         kirkwood_init();
369         if (machine_is_net2big_v2())
370                 kirkwood_mpp_conf(net2big_v2_mpp_config);
371         else
372                 kirkwood_mpp_conf(net5big_v2_mpp_config);
373
374         if (machine_is_net2big_v2())
375                 lacie_v2_hdd_power_init(2);
376         else
377                 lacie_v2_hdd_power_init(5);
378
379         kirkwood_ehci_init();
380         kirkwood_ge00_init(&netxbig_v2_ge00_data);
381         if (machine_is_net5big_v2())
382                 kirkwood_ge01_init(&netxbig_v2_ge01_data);
383         kirkwood_sata_init(&netxbig_v2_sata_data);
384         kirkwood_uart0_init();
385         lacie_v2_register_flash();
386         lacie_v2_register_i2c_devices();
387
388         if (machine_is_net5big_v2())
389                 netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data;
390         platform_device_register(&netxbig_v2_leds);
391         platform_device_register(&netxbig_v2_gpio_buttons);
392
393         if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 &&
394             gpio_direction_output(NETXBIG_V2_GPIO_POWER_OFF, 0) == 0)
395                 pm_power_off = netxbig_v2_power_off;
396         else
397                 pr_err("netxbig_v2: failed to configure power-off GPIO\n");
398 }
399
400 #ifdef CONFIG_MACH_NET2BIG_V2
401 MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2")
402         .boot_params    = 0x00000100,
403         .init_machine   = netxbig_v2_init,
404         .map_io         = kirkwood_map_io,
405         .init_irq       = kirkwood_init_irq,
406         .timer          = &kirkwood_timer,
407 MACHINE_END
408 #endif
409
410 #ifdef CONFIG_MACH_NET5BIG_V2
411 MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2")
412         .boot_params    = 0x00000100,
413         .init_machine   = netxbig_v2_init,
414         .map_io         = kirkwood_map_io,
415         .init_irq       = kirkwood_init_irq,
416         .timer          = &kirkwood_timer,
417 MACHINE_END
418 #endif