Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ts409-setup.c
Go to the documentation of this file.
1 /*
2  * QNAP TS-409 Board Setup
3  *
4  * Maintainer: Sylver Bruneau <[email protected]>
5  *
6  * Copyright (C) 2008 Sylver Bruneau <[email protected]>
7  * Copyright (C) 2008 Martin Michlmayr <[email protected]>
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version
12  * 2 of the License, or (at your option) any later version.
13  */
14 #include <linux/gpio.h>
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/platform_device.h>
18 #include <linux/pci.h>
19 #include <linux/irq.h>
20 #include <linux/mtd/physmap.h>
21 #include <linux/mv643xx_eth.h>
22 #include <linux/leds.h>
23 #include <linux/gpio_keys.h>
24 #include <linux/input.h>
25 #include <linux/i2c.h>
26 #include <linux/serial_reg.h>
27 #include <asm/mach-types.h>
28 #include <asm/mach/arch.h>
29 #include <asm/mach/pci.h>
30 #include <mach/orion5x.h>
31 #include "common.h"
32 #include "mpp.h"
33 #include "tsx09-common.h"
34 
35 /*****************************************************************************
36  * QNAP TS-409 Info
37  ****************************************************************************/
38 
39 /*
40  * QNAP TS-409 hardware :
41  * - Marvell 88F5281-D0
42  * - Marvell 88SX7042 SATA controller (PCIe)
43  * - Marvell 88E1118 Gigabit Ethernet PHY
44  * - RTC S35390A (@0x30) on I2C bus
45  * - 8MB NOR flash
46  * - 256MB of DDR-2 RAM
47  */
48 
49 /*
50  * 8MB NOR flash Device bus boot chip select
51  */
52 
53 #define QNAP_TS409_NOR_BOOT_BASE 0xff800000
54 #define QNAP_TS409_NOR_BOOT_SIZE SZ_8M
55 
56 /****************************************************************************
57  * 8MiB NOR flash. The struct mtd_partition is not in the same order as the
58  * partitions on the device because we want to keep compatibility with
59  * existing QNAP firmware.
60  *
61  * Layout as used by QNAP:
62  * [2] 0x00000000-0x00200000 : "Kernel"
63  * [3] 0x00200000-0x00600000 : "RootFS1"
64  * [4] 0x00600000-0x00700000 : "RootFS2"
65  * [6] 0x00700000-0x00760000 : "NAS Config" (read-only)
66  * [5] 0x00760000-0x00780000 : "U-Boot Config"
67  * [1] 0x00780000-0x00800000 : "U-Boot" (read-only)
68  ***************************************************************************/
69 static struct mtd_partition qnap_ts409_partitions[] = {
70  {
71  .name = "U-Boot",
72  .size = 0x00080000,
73  .offset = 0x00780000,
74  .mask_flags = MTD_WRITEABLE,
75  }, {
76  .name = "Kernel",
77  .size = 0x00200000,
78  .offset = 0,
79  }, {
80  .name = "RootFS1",
81  .size = 0x00400000,
82  .offset = 0x00200000,
83  }, {
84  .name = "RootFS2",
85  .size = 0x00100000,
86  .offset = 0x00600000,
87  }, {
88  .name = "U-Boot Config",
89  .size = 0x00020000,
90  .offset = 0x00760000,
91  }, {
92  .name = "NAS Config",
93  .size = 0x00060000,
94  .offset = 0x00700000,
95  .mask_flags = MTD_WRITEABLE,
96  },
97 };
98 
99 static struct physmap_flash_data qnap_ts409_nor_flash_data = {
100  .width = 1,
101  .parts = qnap_ts409_partitions,
102  .nr_parts = ARRAY_SIZE(qnap_ts409_partitions)
103 };
104 
105 static struct resource qnap_ts409_nor_flash_resource = {
106  .flags = IORESOURCE_MEM,
107  .start = QNAP_TS409_NOR_BOOT_BASE,
109 };
110 
111 static struct platform_device qnap_ts409_nor_flash = {
112  .name = "physmap-flash",
113  .id = 0,
114  .dev = { .platform_data = &qnap_ts409_nor_flash_data, },
115  .num_resources = 1,
116  .resource = &qnap_ts409_nor_flash_resource,
117 };
118 
119 /*****************************************************************************
120  * PCI
121  ****************************************************************************/
122 
123 static int __init qnap_ts409_pci_map_irq(const struct pci_dev *dev, u8 slot,
124  u8 pin)
125 {
126  int irq;
127 
128  /*
129  * Check for devices with hard-wired IRQs.
130  */
131  irq = orion5x_pci_map_irq(dev, slot, pin);
132  if (irq != -1)
133  return irq;
134 
135  /*
136  * PCI isn't used on the TS-409
137  */
138  return -1;
139 }
140 
141 static struct hw_pci qnap_ts409_pci __initdata = {
142  .nr_controllers = 2,
143  .setup = orion5x_pci_sys_setup,
144  .scan = orion5x_pci_sys_scan_bus,
145  .map_irq = qnap_ts409_pci_map_irq,
146 };
147 
148 static int __init qnap_ts409_pci_init(void)
149 {
150  if (machine_is_ts409())
151  pci_common_init(&qnap_ts409_pci);
152 
153  return 0;
154 }
155 
156 subsys_initcall(qnap_ts409_pci_init);
157 
158 /*****************************************************************************
159  * RTC S35390A on I2C bus
160  ****************************************************************************/
161 
162 #define TS409_RTC_GPIO 10
163 
164 static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = {
165  I2C_BOARD_INFO("s35390a", 0x30),
166 };
167 
168 /*****************************************************************************
169  * LEDs attached to GPIO
170  ****************************************************************************/
171 
172 static struct gpio_led ts409_led_pins[] = {
173  {
174  .name = "ts409:red:sata1",
175  .gpio = 4,
176  .active_low = 1,
177  }, {
178  .name = "ts409:red:sata2",
179  .gpio = 5,
180  .active_low = 1,
181  }, {
182  .name = "ts409:red:sata3",
183  .gpio = 6,
184  .active_low = 1,
185  }, {
186  .name = "ts409:red:sata4",
187  .gpio = 7,
188  .active_low = 1,
189  },
190 };
191 
192 static struct gpio_led_platform_data ts409_led_data = {
193  .leds = ts409_led_pins,
194  .num_leds = ARRAY_SIZE(ts409_led_pins),
195 };
196 
197 static struct platform_device ts409_leds = {
198  .name = "leds-gpio",
199  .id = -1,
200  .dev = {
201  .platform_data = &ts409_led_data,
202  },
203 };
204 
205 /****************************************************************************
206  * GPIO Attached Keys
207  * Power button is attached to the PIC microcontroller
208  ****************************************************************************/
209 
210 #define QNAP_TS409_GPIO_KEY_RESET 14
211 #define QNAP_TS409_GPIO_KEY_MEDIA 15
212 
213 static struct gpio_keys_button qnap_ts409_buttons[] = {
214  {
215  .code = KEY_RESTART,
217  .desc = "Reset Button",
218  .active_low = 1,
219  }, {
220  .code = KEY_COPY,
222  .desc = "USB Copy Button",
223  .active_low = 1,
224  },
225 };
226 
227 static struct gpio_keys_platform_data qnap_ts409_button_data = {
228  .buttons = qnap_ts409_buttons,
229  .nbuttons = ARRAY_SIZE(qnap_ts409_buttons),
230 };
231 
232 static struct platform_device qnap_ts409_button_device = {
233  .name = "gpio-keys",
234  .id = -1,
235  .num_resources = 0,
236  .dev = {
237  .platform_data = &qnap_ts409_button_data,
238  },
239 };
240 
241 /*****************************************************************************
242  * General Setup
243  ****************************************************************************/
244 static unsigned int ts409_mpp_modes[] __initdata = {
245  MPP0_UNUSED,
246  MPP1_UNUSED,
247  MPP2_UNUSED,
248  MPP3_UNUSED,
249  MPP4_GPIO, /* HDD 1 status */
250  MPP5_GPIO, /* HDD 2 status */
251  MPP6_GPIO, /* HDD 3 status */
252  MPP7_GPIO, /* HDD 4 status */
253  MPP8_UNUSED,
254  MPP9_UNUSED,
255  MPP10_GPIO, /* RTC int */
256  MPP11_UNUSED,
257  MPP12_UNUSED,
258  MPP13_UNUSED,
259  MPP14_GPIO, /* SW_RST */
260  MPP15_GPIO, /* USB copy button */
261  MPP16_UART, /* UART1 RXD */
262  MPP17_UART, /* UART1 TXD */
263  MPP18_UNUSED,
264  MPP19_UNUSED,
265  0,
266 };
267 
268 static void __init qnap_ts409_init(void)
269 {
270  /*
271  * Setup basic Orion functions. Need to be called early.
272  */
273  orion5x_init();
274 
275  orion5x_mpp_conf(ts409_mpp_modes);
276 
277  /*
278  * Configure peripherals.
279  */
282  platform_device_register(&qnap_ts409_nor_flash);
283 
286  qnap_ts409_partitions[5].offset,
287  qnap_ts409_partitions[5].size);
292 
293  platform_device_register(&qnap_ts409_button_device);
294 
295  /* Get RTC IRQ and register the chip */
296  if (gpio_request(TS409_RTC_GPIO, "rtc") == 0) {
298  qnap_ts409_i2c_rtc.irq = gpio_to_irq(TS409_RTC_GPIO);
299  else
301  }
302  if (qnap_ts409_i2c_rtc.irq == 0)
303  pr_warning("qnap_ts409_init: failed to get RTC IRQ\n");
304  i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1);
305  platform_device_register(&ts409_leds);
306 
307  /* register tsx09 specific power-off method */
309 }
310 
311 MACHINE_START(TS409, "QNAP TS-409")
312  /* Maintainer: Sylver Bruneau <[email protected]> */
313  .atag_offset = 0x100,
314  .init_machine = qnap_ts409_init,
315  .map_io = orion5x_map_io,
316  .init_early = orion5x_init_early,
317  .init_irq = orion5x_init_irq,
318  .timer = &orion5x_timer,
319  .fixup = tag_fixup_mem32,
320  .restart = orion5x_restart,