Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
d2net-setup.c
Go to the documentation of this file.
1 /*
2  * arch/arm/mach-orion5x/d2net-setup.c
3  *
4  * LaCie d2Network and Big Disk Network NAS setup
5  *
6  * Copyright (C) 2009 Simon Guinot <[email protected]>
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/pci.h>
17 #include <linux/irq.h>
18 #include <linux/mtd/physmap.h>
19 #include <linux/mv643xx_eth.h>
20 #include <linux/leds.h>
21 #include <linux/gpio_keys.h>
22 #include <linux/input.h>
23 #include <linux/i2c.h>
24 #include <linux/ata_platform.h>
25 #include <linux/gpio.h>
26 #include <asm/mach-types.h>
27 #include <asm/mach/arch.h>
28 #include <asm/mach/pci.h>
29 #include <mach/orion5x.h>
30 #include <plat/orion-gpio.h>
31 #include "common.h"
32 #include "mpp.h"
33 
34 /*****************************************************************************
35  * LaCie d2 Network Info
36  ****************************************************************************/
37 
38 /*
39  * 512KB NOR flash Device bus boot chip select
40  */
41 
42 #define D2NET_NOR_BOOT_BASE 0xfff80000
43 #define D2NET_NOR_BOOT_SIZE SZ_512K
44 
45 /*****************************************************************************
46  * 512KB NOR Flash on Boot Device
47  ****************************************************************************/
48 
49 /*
50  * TODO: Check write support on flash MX29LV400CBTC-70G
51  */
52 
53 static struct mtd_partition d2net_partitions[] = {
54  {
55  .name = "Full512kb",
56  .size = MTDPART_SIZ_FULL,
57  .offset = 0,
58  .mask_flags = MTD_WRITEABLE,
59  },
60 };
61 
62 static struct physmap_flash_data d2net_nor_flash_data = {
63  .width = 1,
64  .parts = d2net_partitions,
65  .nr_parts = ARRAY_SIZE(d2net_partitions),
66 };
67 
68 static struct resource d2net_nor_flash_resource = {
69  .flags = IORESOURCE_MEM,
70  .start = D2NET_NOR_BOOT_BASE,
71  .end = D2NET_NOR_BOOT_BASE
72  + D2NET_NOR_BOOT_SIZE - 1,
73 };
74 
75 static struct platform_device d2net_nor_flash = {
76  .name = "physmap-flash",
77  .id = 0,
78  .dev = {
79  .platform_data = &d2net_nor_flash_data,
80  },
81  .num_resources = 1,
82  .resource = &d2net_nor_flash_resource,
83 };
84 
85 /*****************************************************************************
86  * Ethernet
87  ****************************************************************************/
88 
89 static struct mv643xx_eth_platform_data d2net_eth_data = {
90  .phy_addr = MV643XX_ETH_PHY_ADDR(8),
91 };
92 
93 /*****************************************************************************
94  * I2C devices
95  ****************************************************************************/
96 
97 /*
98  * i2c addr | chip | description
99  * 0x32 | Ricoh 5C372b | RTC
100  * 0x3e | GMT G762 | PWM fan controller
101  * 0x50 | HT24LC08 | eeprom (1kB)
102  *
103  * TODO: Add G762 support to the g760a driver.
104  */
105 static struct i2c_board_info __initdata d2net_i2c_devices[] = {
106  {
107  I2C_BOARD_INFO("rs5c372b", 0x32),
108  }, {
109  I2C_BOARD_INFO("24c08", 0x50),
110  },
111 };
112 
113 /*****************************************************************************
114  * SATA
115  ****************************************************************************/
116 
117 static struct mv_sata_platform_data d2net_sata_data = {
118  .n_ports = 2,
119 };
120 
121 #define D2NET_GPIO_SATA0_POWER 3
122 #define D2NET_GPIO_SATA1_POWER 12
123 
124 static void __init d2net_sata_power_init(void)
125 {
126  int err;
127 
128  err = gpio_request(D2NET_GPIO_SATA0_POWER, "SATA0 power");
129  if (err == 0) {
131  if (err)
133  }
134  if (err)
135  pr_err("d2net: failed to configure SATA0 power GPIO\n");
136 
137  err = gpio_request(D2NET_GPIO_SATA1_POWER, "SATA1 power");
138  if (err == 0) {
140  if (err)
142  }
143  if (err)
144  pr_err("d2net: failed to configure SATA1 power GPIO\n");
145 }
146 
147 /*****************************************************************************
148  * GPIO LED's
149  ****************************************************************************/
150 
151 /*
152  * The blue front LED is wired to the CPLD and can blink in relation with the
153  * SATA activity.
154  *
155  * The following array detail the different LED registers and the combination
156  * of their possible values:
157  *
158  * led_off | blink_ctrl | SATA active | LED state
159  * | | |
160  * 1 | x | x | off
161  * 0 | 0 | 0 | off
162  * 0 | 1 | 0 | blink (rate 300ms)
163  * 0 | x | 1 | on
164  *
165  * Notes: The blue and the red front LED's can't be on at the same time.
166  * Red LED have priority.
167  */
168 
169 #define D2NET_GPIO_RED_LED 6
170 #define D2NET_GPIO_BLUE_LED_BLINK_CTRL 16
171 #define D2NET_GPIO_BLUE_LED_OFF 23
172 
173 static struct gpio_led d2net_leds[] = {
174  {
175  .name = "d2net:blue:sata",
176  .default_trigger = "default-on",
177  .gpio = D2NET_GPIO_BLUE_LED_OFF,
178  .active_low = 1,
179  },
180  {
181  .name = "d2net:red:fail",
182  .gpio = D2NET_GPIO_RED_LED,
183  },
184 };
185 
186 static struct gpio_led_platform_data d2net_led_data = {
187  .num_leds = ARRAY_SIZE(d2net_leds),
188  .leds = d2net_leds,
189 };
190 
191 static struct platform_device d2net_gpio_leds = {
192  .name = "leds-gpio",
193  .id = -1,
194  .dev = {
195  .platform_data = &d2net_led_data,
196  },
197 };
198 
199 static void __init d2net_gpio_leds_init(void)
200 {
201  int err;
202 
203  /* Configure GPIO over MPP max number. */
205 
206  /* Configure register blink_ctrl to allow SATA activity LED blinking. */
207  err = gpio_request(D2NET_GPIO_BLUE_LED_BLINK_CTRL, "blue LED blink");
208  if (err == 0) {
210  if (err)
212  }
213  if (err)
214  pr_err("d2net: failed to configure blue LED blink GPIO\n");
215 
216  platform_device_register(&d2net_gpio_leds);
217 }
218 
219 /****************************************************************************
220  * GPIO keys
221  ****************************************************************************/
222 
223 #define D2NET_GPIO_PUSH_BUTTON 18
224 #define D2NET_GPIO_POWER_SWITCH_ON 8
225 #define D2NET_GPIO_POWER_SWITCH_OFF 9
226 
227 #define D2NET_SWITCH_POWER_ON 0x1
228 #define D2NET_SWITCH_POWER_OFF 0x2
229 
230 static struct gpio_keys_button d2net_buttons[] = {
231  {
232  .type = EV_SW,
233  .code = D2NET_SWITCH_POWER_OFF,
235  .desc = "Power rocker switch (auto|off)",
236  .active_low = 0,
237  },
238  {
239  .type = EV_SW,
240  .code = D2NET_SWITCH_POWER_ON,
242  .desc = "Power rocker switch (on|auto)",
243  .active_low = 0,
244  },
245  {
246  .type = EV_KEY,
247  .code = KEY_POWER,
248  .gpio = D2NET_GPIO_PUSH_BUTTON,
249  .desc = "Front Push Button",
250  .active_low = 0,
251  },
252 };
253 
254 static struct gpio_keys_platform_data d2net_button_data = {
255  .buttons = d2net_buttons,
256  .nbuttons = ARRAY_SIZE(d2net_buttons),
257 };
258 
259 static struct platform_device d2net_gpio_buttons = {
260  .name = "gpio-keys",
261  .id = -1,
262  .dev = {
263  .platform_data = &d2net_button_data,
264  },
265 };
266 
267 /*****************************************************************************
268  * General Setup
269  ****************************************************************************/
270 
271 static unsigned int d2net_mpp_modes[] __initdata = {
272  MPP0_GPIO, /* Board ID (bit 0) */
273  MPP1_GPIO, /* Board ID (bit 1) */
274  MPP2_GPIO, /* Board ID (bit 2) */
275  MPP3_GPIO, /* SATA 0 power */
276  MPP4_UNUSED,
277  MPP5_GPIO, /* Fan fail detection */
278  MPP6_GPIO, /* Red front LED */
279  MPP7_UNUSED,
280  MPP8_GPIO, /* Rear power switch (on|auto) */
281  MPP9_GPIO, /* Rear power switch (auto|off) */
282  MPP10_UNUSED,
283  MPP11_UNUSED,
284  MPP12_GPIO, /* SATA 1 power */
285  MPP13_UNUSED,
286  MPP14_SATA_LED, /* SATA 0 active */
287  MPP15_SATA_LED, /* SATA 1 active */
288  MPP16_GPIO, /* Blue front LED blink control */
289  MPP17_UNUSED,
290  MPP18_GPIO, /* Front button (0 = Released, 1 = Pushed ) */
291  MPP19_UNUSED,
292  0,
293  /* 22: USB port 1 fuse (0 = Fail, 1 = Ok) */
294  /* 23: Blue front LED off */
295  /* 24: Inhibit board power off (0 = Disabled, 1 = Enabled) */
296 };
297 
298 #define D2NET_GPIO_INHIBIT_POWER_OFF 24
299 
300 static void __init d2net_init(void)
301 {
302  /*
303  * Setup basic Orion functions. Need to be called early.
304  */
305  orion5x_init();
306 
307  orion5x_mpp_conf(d2net_mpp_modes);
308 
309  /*
310  * Configure peripherals.
311  */
313  orion5x_eth_init(&d2net_eth_data);
316 
317  d2net_sata_power_init();
318  orion5x_sata_init(&d2net_sata_data);
319 
322  platform_device_register(&d2net_nor_flash);
323 
324  platform_device_register(&d2net_gpio_buttons);
325 
326  d2net_gpio_leds_init();
327 
328  pr_notice("d2net: Flash write are not yet supported.\n");
329 
330  i2c_register_board_info(0, d2net_i2c_devices,
331  ARRAY_SIZE(d2net_i2c_devices));
332 
334 }
335 
336 /* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
337 
338 #ifdef CONFIG_MACH_D2NET
339 MACHINE_START(D2NET, "LaCie d2 Network")
340  .atag_offset = 0x100,
341  .init_machine = d2net_init,
342  .map_io = orion5x_map_io,
343  .init_early = orion5x_init_early,
344  .init_irq = orion5x_init_irq,
345  .timer = &orion5x_timer,
346  .fixup = tag_fixup_mem32,
347  .restart = orion5x_restart,
349 #endif
350 
351 #ifdef CONFIG_MACH_BIGDISK
352 MACHINE_START(BIGDISK, "LaCie Big Disk Network")
353  .atag_offset = 0x100,
354  .init_machine = d2net_init,
355  .map_io = orion5x_map_io,
356  .init_early = orion5x_init_early,
357  .init_irq = orion5x_init_irq,
358  .timer = &orion5x_timer,
359  .fixup = tag_fixup_mem32,
360  .restart = orion5x_restart,
362 #endif
363